Jump to content
Bilgus

FiFo Queue - Simple

Recommended Posts

Went looking for a FIFO queue there are a few examples here on the forum but I didn't like the complexit/lack of flexibility in what I found

The Queue Ive implemented uses a single dimension array  set up as a circular buffer

The position and Item Count are stored in an extra slot of the array inside a 'DllStruct'

Convenience Functions are included

FifoQueue_Create($iSlots) ;Initialize the Queue

Func FifoQueue_($eFQ, ByRef $aQ) ;For Status Functions - (So you don't have to supply $vOut)

Available operations:

$eFQ_Create = 0, $eFQ_Push, $eFQ_Peek, $eFQ_Pop, $eFQ_IsEmpty, $eFQ_IsFull, $eFQ_Count, $eFQ_Empty, $eFQ_IsInit
Spoiler
Global Enum $eFQ_Create = 0, $eFQ_Push, $eFQ_Peek, $eFQ_Pop, $eFQ_IsEmpty, $eFQ_IsFull, $eFQ_Count, $eFQ_Empty, $eFQ_IsInit

Func FifoQueue($eFQ, ByRef $aQ, ByRef $vOut)
    ;Bilgus 2020
    Local Const $IDInit = 0xF1F0

    Local $iErr = 0
    Local $iPos, $iItems
    Local $tKey, $IDKey
    Local $iSlots = UBound($aQ, 1) - 1
    If $iSlots > 0xFFFE Then Return SetError(0xFFFE, -1, $vOut)

    If $eFQ <> $eFQ_Create Then
        If Not IsArray($aQ) Or $iSlots < 2 Then
            $iErr = 1 ;Queue not initialized
        ElseIf IsDllStruct($aQ[$iSlots]) Then
            $tKey = $aQ[$iSlots] ;MQ_Create adds an extra Slot -- pos data is stored there..
            $iPos = DllStructGetData($tKey, 1, 1)
            $iItems = DllStructGetData($tKey, 1, 2)
            If DllStructGetData($tKey, 1, 3) <> $IDInit Then $iErr += 2 ;Queue not initialized (BY MQ_Create)
        EndIf

        If $iErr And $eFQ <> $eFQ_IsInit Then
            ConsoleWrite("Queue Error: " & $iErr & @CRLF)
            Return SetError($iErr, 0, $vOut)
        EndIf
    Else
        If $iSlots < 2 Then $iSlots = 10
        Local $a[$iSlots + 1]
        $tKey = DllStructCreate("USHORT[4]")
        DllStructSetData($tKey, 1, 0xF1F0, 3)
        $a[$iSlots] = $tKey
        $vOut = $a
        ;ConsoleWrite("Created Queue[" & $iSlots & "]" & @CRLF)
        Return SetError($iErr, $iSlots, $vOut)
    EndIf
    ;Circular Queue Logic
    Switch ($eFQ)
        Case $eFQ_Push
            If $iItems >= $iSlots Then Return False
             ;Rollover after last element
            $aQ[Mod($iItems + $iPos, $iSlots)] = $vOut
            $iItems += 1
        Case $eFQ_Peek
            If $iItems = 0 Then Return False
            $vOut = $aQ[$iPos]
        Case $eFQ_Pop
            If $iItems = 0 Then Return False
            $vOut = $aQ[$iPos]
            $iPos += 1
            $iItems -= 1
        Case $eFQ_IsEmpty
            Return ($iItems = 0)
        Case $eFQ_IsFull
            Return ($iItems >= $iSlots)
        Case $eFQ_Count
            Return $iItems
        Case $eFQ_Empty
            $iItems = 0
        Case $eFQ_IsInit
            Return ($iErr = 0)
        Case Else
            Return False
    EndSwitch

    $iPos = Mod($iPos, $iSlots) ;Rollover after last element
    DllStructSetData($tKey, 1, $iPos, 1)
    DllStructSetData($tKey, 1, $iItems, 2)
    Return SetError($iErr, $iItems, True)
EndFunc   ;==>FifoQueue



;--Convenience Functions-------------------------------
Func FifoQueue_Create($iSlots = 10)
    Local $aE
    Return FifoQueue($eFQ_Create, $iSlots, $aE)
EndFunc   ;==>FifoQueue_Create

Func FifoQueue_($eFQ, ByRef $aQ)
    Local $aE
    If $eFQ < $eFQ_IsEmpty Then
        $aE = FifoQueue($eFQ, $aQ, $aE)
        Return SetError(@error, 0, $aE)
    Else
        Return FifoQueue($eFQ, $aQ, $aE)
    EndIf
EndFunc   ;==>FifoQueue_
;--Convenience Functions-------------------------------

 

Example (With Debug function)

Spoiler
;Bilgus 2020
Global Enum $eFQ_Create = 0, $eFQ_Push, $eFQ_Peek, $eFQ_Pop, $eFQ_IsEmpty, $eFQ_IsFull, $eFQ_Count, $eFQ_Empty, $eFQ_IsInit
Global $aQueue
ConsoleWrite("!Queue" & (FifoQueue_($eFQ_IsInit, $aQueue) ? " IS " : " NOT ") & "initialized" & @CRLF)
$aQueue = FifoQueue_Create(4)
ConsoleWrite("!Queue" & (FifoQueue_($eFQ_IsInit, $aQueue) ? " IS " : " NOT ") & "initialized" & @CRLF)

FifoQueueTest()


Func FifoQueueTest()
    Local $aTest
    If FifoQueue_Dbg($eFQ_Pop, $aQueue, $aTest) Then ConsoleWrite(StringFormat("!%s, %s, %s, %s" & @CRLF, $aTest[0], $aTest[1], $aTest[2], $aTest[3]))
    ConsoleWrite("!Push 9" & @CRLF)
    For $i = 0 To 80 Step 10
        Local $aIn[4] = [$i, $i + 1, $i + 2, $i + 3]
        If FifoQueue_Dbg($eFQ_Push, $aQueue, $aIn) Then
            ConsoleWrite(StringFormat("%s, %s, %s, %s" & @CRLF, $aIn[0], $aIn[1], $aIn[2], $aIn[3]))
        EndIf
    Next
    ConsoleWrite("!Pop All" & @CRLF)
    While FifoQueue_Dbg($eFQ_Pop, $aQueue, $aTest)
        ConsoleWrite(StringFormat("%s, %s, %s, %s" & @CRLF, $aTest[0], $aTest[1], $aTest[2], $aTest[3]))
    WEnd
    ConsoleWrite("!Push 9" & @CRLF)
    For $i = 100 To 900 Step 100
        Local $aIn[4] = [$i, $i + 1, $i + 2, $i + 3]
        If FifoQueue_Dbg($eFQ_Push, $aQueue, $aIn) Then
            ConsoleWrite(StringFormat("%s, %s, %s, %s" & @CRLF, $aIn[0], $aIn[1], $aIn[2], $aIn[3]))
        EndIf
    Next
    ConsoleWrite("!Queue" & (FifoQueue_($eFQ_IsFull, $aQueue) ? " IS " : " NOT ") & "full" & @CRLF)
    ConsoleWrite("!Queue Items: " & FifoQueue_($eFQ_Count, $aQueue) & @CRLF)
    ConsoleWrite("!Push 1" & @CRLF)
    Local $aIn[6] = [5555, 6666, 7777, 8888]
    FifoQueue_Dbg($eFQ_Push, $aQueue, $aIn)
    ConsoleWrite(StringFormat("%s, %s, %s, %s" & @CRLF, $aIn[0], $aIn[1], $aIn[2], $aIn[3]))

    
    If FifoQueue_Dbg($eFQ_Peek, $aQueue, $aTest) Then ConsoleWrite(StringFormat("%s, %s, %s, %s" & @CRLF, $aTest[0], $aTest[1], $aTest[2], $aTest[3]))
    ConsoleWrite("!Pop 2" & @CRLF)
    If FifoQueue_Dbg($eFQ_Pop, $aQueue, $aTest) Then ConsoleWrite(StringFormat("%s, %s, %s, %s" & @CRLF, $aTest[0], $aTest[1], $aTest[2], $aTest[3]))
    If FifoQueue_Dbg($eFQ_Pop, $aQueue, $aTest) Then ConsoleWrite(StringFormat("%s, %s, %s, %s" & @CRLF, $aTest[0], $aTest[1], $aTest[2], $aTest[3]))
    ConsoleWrite("!Queue" & (FifoQueue_($eFQ_IsFull, $aQueue) ? " IS " : " NOT ") & "full" & @CRLF)
    ConsoleWrite("!Queue Items: " & FifoQueue_($eFQ_Count, $aQueue) & @CRLF)
    ConsoleWrite("!Push 4" & @CRLF)
    For $i = 1000 To 5000 Step 1000
        Local $aIn[4] = [$i, $i + 1, $i + 2, $i + 3]
        If FifoQueue_Dbg($eFQ_Push, $aQueue, $aIn) Then
            ConsoleWrite(StringFormat("%s, %s, %s, %s" & @CRLF, $aIn[0], $aIn[1], $aIn[2], $aIn[3]))
        EndIf
    Next
    ConsoleWrite("!Pop 2" & @CRLF)
    For $i = 1 To 2
        If FifoQueue_Dbg($eFQ_Pop, $aQueue, $aTest) Then ConsoleWrite(StringFormat("%s, %s, %s, %s" & @CRLF, $aTest[0], $aTest[1], $aTest[2], $aTest[3]))
    Next
    ConsoleWrite("!Push 7" & @CRLF)
    For $i = 10000 To 70000 Step 10000
        Local $aIn[4] = [$i, $i + 1, $i + 2, $i + 3]
        If FifoQueue_Dbg($eFQ_Push, $aQueue, $aIn) Then
            ConsoleWrite(StringFormat("%s, %s, %s, %s" & @CRLF, $aIn[0], $aIn[1], $aIn[2], $aIn[3]))
        EndIf
    Next
    ConsoleWrite("!Pop 2" & @CRLF)
    For $i = 1 To 2
        If FifoQueue_Dbg($eFQ_Pop, $aQueue, $aTest) Then ConsoleWrite(StringFormat("%s, %s, %s, %s" & @CRLF, $aTest[0], $aTest[1], $aTest[2], $aTest[3]))
    Next
    ConsoleWrite("!PopAll" & @CRLF)
    While FifoQueue_Dbg($eFQ_Pop, $aQueue, $aTest)
        ConsoleWrite(StringFormat("%s, %s, %s, %s" & @CRLF, $aTest[0], $aTest[1], $aTest[2], $aTest[3]))
    WEnd
    ConsoleWrite("!Queue" & (FifoQueue_($eFQ_IsEmpty, $aQueue) ? " IS " : " NOT ") & "empty" & @CRLF)
    ConsoleWrite("!Push 6" & @CRLF)
    For $i = 0 To 50 Step 10
        Local $aIn[4] = [$i, $i + 1, $i + 2, $i + 3]
        If FifoQueue_Dbg($eFQ_Push, $aQueue, $aIn) Then
            ConsoleWrite(StringFormat("%s, %s, %s, %s" & @CRLF, $aIn[0], $aIn[1], $aIn[2], $aIn[3]))
        EndIf
    Next
    ConsoleWrite("!Pop 4 [2]" & @CRLF)
    Local $aTest[2]
    For $i = 1 To 4
        If FifoQueue_Dbg($eFQ_Pop, $aQueue, $aTest) Then ConsoleWrite(StringFormat("%s, %s" & @CRLF, $aTest[0], $aTest[1]))
    Next
    Local $aTest = 0
    ConsoleWrite("!Push 7" & @CRLF)
    For $i = 100 To 700 Step 100
        Local $aIn[4] = ["N" & $i, $i + 1, $i + 2, $i + 3]
        If FifoQueue_Dbg($eFQ_Push, $aQueue, $aIn) Then
            ConsoleWrite(StringFormat("%s, %s, %s, %s" & @CRLF, $aIn[0], $aIn[1], $aIn[2], $aIn[3]))
        EndIf
    Next
    ConsoleWrite("!Empty All" & @CRLF)
    FifoQueue_($eFQ_Empty, $aQueue)
    ConsoleWrite("!Queue" & (FifoQueue_($eFQ_IsEmpty, $aQueue) ? " IS " : " NOT ") & "empty" & @CRLF)
    ConsoleWrite("!Push 10" & @CRLF)
    For $i = 0 To 9
        Local $aIn[4] = ["A" & $i, $i + 1, $i + 2, $i + 3]
        If FifoQueue_Dbg($eFQ_Push, $aQueue, $aIn) Then
            ConsoleWrite(StringFormat("%s, %s, %s, %s" & @CRLF, $aIn[0], $aIn[1], $aIn[2], $aIn[3]))
        EndIf
    Next
    ConsoleWrite("!Pop 2" & @CRLF)
    If FifoQueue_Dbg($eFQ_Pop, $aQueue, $aTest) Then ConsoleWrite(StringFormat("%s, %s, %s, %s" & @CRLF, $aTest[0], $aTest[1], $aTest[2], $aTest[3]))
    If FifoQueue_Dbg($eFQ_Pop, $aQueue, $aTest) Then ConsoleWrite(StringFormat("%s, %s, %s, %s" & @CRLF, $aTest[0], $aTest[1], $aTest[2], $aTest[3]))
    ConsoleWrite("!Push 1" & @CRLF)
    Local $aIn[6] = [5555, 6666, 7777, 8888]
    FifoQueue_Dbg($eFQ_Push, $aQueue, $aIn)
    ConsoleWrite(StringFormat("%s, %s, %s, %s" & @CRLF, $aIn[0], $aIn[1], $aIn[2], $aIn[3]))
    ConsoleWrite("!Pop 2" & @CRLF)
    If FifoQueue_Dbg($eFQ_Pop, $aQueue, $aTest) Then ConsoleWrite(StringFormat("%s, %s, %s, %s" & @CRLF, $aTest[0], $aTest[1], $aTest[2], $aTest[3]))
    If FifoQueue_Dbg($eFQ_Pop, $aQueue, $aTest) Then ConsoleWrite(StringFormat("%s, %s, %s, %s" & @CRLF, $aTest[0], $aTest[1], $aTest[2], $aTest[3]))
    ConsoleWrite("!Push 2" & @CRLF)
    Local $aIn[4] = ["P" & 0, 1, 2, 3]
    If FifoQueue_Dbg($eFQ_Push, $aQueue, $aIn) Then
        ConsoleWrite(StringFormat("%s, %s, %s, %s" & @CRLF, $aIn[0], $aIn[1], $aIn[2], $aIn[3]))
    EndIf
    Local $aIn[4] = ["P" & 10, 20, 30, 40]
    If FifoQueue_Dbg($eFQ_Push, $aQueue, $aIn) Then
        ConsoleWrite(StringFormat("%s, %s, %s, %s" & @CRLF, $aIn[0], $aIn[1], $aIn[2], $aIn[3]))
    EndIf
    ConsoleWrite("!Queue Items: " & FifoQueue_($eFQ_Count, $aQueue) & @CRLF)
    ConsoleWrite("!PopAll" & @CRLF)
    While FifoQueue_Dbg($eFQ_Pop, $aQueue, $aTest)
        ConsoleWrite(StringFormat("%s, %s, %s, %s" & @CRLF, $aTest[0], $aTest[1], $aTest[2], $aTest[3]))
    WEnd
EndFunc   ;==>FifoQueueTest

;--Convenience Functions-------------------------------
Func FifoQueue_Create($iSlots = 10)
    Local $aE
    Return FifoQueue($eFQ_Create, $iSlots, $aE)
EndFunc   ;==>FifoQueue_Create

Func FifoQueue_($eFQ, ByRef $aQ)
    Local $aE
    If $eFQ < $eFQ_IsEmpty Then
        $aE = FifoQueue($eFQ, $aQ, $aE)
        Return SetError(@error, 0, $aE)
    Else
        Return FifoQueue($eFQ, $aQ, $aE)
    EndIf
EndFunc   ;==>FifoQueue_
;--Convenience Functions-------------------------------

Func FifoQueue_Dbg($eFQ, ByRef $aQ, ByRef $vOut)
    Local Const $aDbg[9] = ["<>Create", ">Push [%d]", "<Peek [%d]", "<Pop [%d]", "=IsEmpty", "=IsFull", "=Count", "<>Empty", "=IsInit"]

    Local $iSlots = UBound($aQ, 1) - 1
    If $iSlots > 65534 Then MsgBox(0, "ERROR", "Too many Slots")

    If $iSlots > 0 Then
        If IsDllStruct($aQ[$iSlots]) Then
            $tKey = $aQ[$iSlots]
            Local $iElKey = DllStructGetData($tKey, 1, 3)
            Local $iItems = DllStructGetData($tKey, 1, 2)
            Local $iPos = DllStructGetData($tKey, 1, 1)
            If $eFQ > $eFQ_Pop Then
                ConsoleWrite($aDbg[$eFQ] & @CRLF)
            ElseIf $eFQ = $eFQ_Push Then
                ConsoleWrite(StringFormat($aDbg[$eFQ] & @CRLF, Mod($iItems + $iPos, $iSlots)))
            Else
                ConsoleWrite(StringFormat($aDbg[$eFQ] & @CRLF, $iPos))
            EndIf
        Else
            ConsoleWrite("Invalid Array $aQ" & @CRLF)
        EndIf
    Else
        ConsoleWrite($aDbg[$eFQ] & @CRLF)
    EndIf
    Local $aRes = FifoQueue($eFQ, $aQ, $vOut)

    Return $aRes
EndFunc   ;==>FifoQueue_Dbg

Func FifoQueue($eFQ, ByRef $aQ, ByRef $vOut)
                    ;Bilgus 2020
    Local Const $IDInit = 0xF1F0

    Local $iErr = 0
    Local $iPos, $iItems
    Local $tKey, $IDKey
    Local $iSlots = UBound($aQ, 1) - 1
    If $iSlots > 0xFFFE Then Return SetError(0xFFFE, -1, $vOut)

    If $eFQ <> $eFQ_Create Then
        If Not IsArray($aQ) Or $iSlots < 2 Then
            $iErr = 1 ;Queue not initialized
        ElseIf IsDllStruct($aQ[$iSlots]) Then
            $tKey = $aQ[$iSlots] ;MQ_Create adds an extra Slot -- pos data is stored there..
            $iPos = DllStructGetData($tKey, 1, 1)
            $iItems = DllStructGetData($tKey, 1, 2)
            If DllStructGetData($tKey, 1, 3) <> $IDInit Then $iErr += 2 ;Queue not initialized (BY MQ_Create)
        EndIf

        If $iErr And $eFQ <> $eFQ_IsInit Then
            ConsoleWrite("Queue Error: " & $iErr & @CRLF)
            Return SetError($iErr, 0, $vOut)
        EndIf
    Else
        If $iSlots < 2 Then $iSlots = 10
        Local $a[$iSlots + 1]
        $tKey = DllStructCreate("USHORT[4]")
        DllStructSetData($tKey, 1, 0xF1F0, 3)
        $a[$iSlots] = $tKey
        $vOut = $a
        ;ConsoleWrite("Created Queue[" & $iSlots & "]" & @CRLF)
        Return SetError($iErr, $iSlots, $vOut)
    EndIf
    ;Circular Queue Logic
    Switch ($eFQ)
        Case $eFQ_Push
            If $iItems >= $iSlots Then Return False
             ;Rollover after last element
            $aQ[Mod($iItems + $iPos, $iSlots)] = $vOut
            $iItems += 1
        Case $eFQ_Peek
            If $iItems = 0 Then Return False
            $vOut = $aQ[$iPos]
        Case $eFQ_Pop
            If $iItems = 0 Then Return False
            $vOut = $aQ[$iPos]
            $iPos += 1
            $iItems -= 1
        Case $eFQ_IsEmpty
            Return ($iItems = 0)
        Case $eFQ_IsFull
            Return ($iItems >= $iSlots)
        Case $eFQ_Count
            Return $iItems
        Case $eFQ_Empty
            $iItems = 0
        Case $eFQ_IsInit
            Return ($iErr = 0)
        Case Else
            Return False
    EndSwitch

    $iPos = Mod($iPos, $iSlots) ;Rollover after last element
    DllStructSetData($tKey, 1, $iPos, 1)
    DllStructSetData($tKey, 1, $iItems, 2)
    Return SetError($iErr, $iItems, True)
EndFunc   ;==>FifoQueue

 

 

Share this post


Link to post
Share on other sites

Here is a second version with Redim supported

Note redim only works when items are in the array if you are making it larger

Queue needs to be empty to redim smaller.

It also BitXORs the number of slots with 0xF1F0 to be a bit more robust with checking if the Queue array is valid

Spoiler
Global Enum $eFQ_Create = 0, $eFQ_Push, $eFQ_Peek, $eFQ_Pop, $eFQ_Redim, $eFQ_Empty, $eFQ_IsEmpty, $eFQ_IsFull, $eFQ_Count, $eFQ_IsInit, $eFQ_ENUMCOUNT

Func FifoQueue($eFQ, ByRef $aQ, ByRef $vOut)
    Local Const $IDInit = 0xF1F0, $_FQ_Error = -1
    Local Enum $eiPos = 1, $eiItems, $eID, $eiSlots
    Local $tKey, $iPos, $iItems, $iErr = 0
    Local $iSlots = UBound($aQ, 1) - 1
    If $iSlots > 0xFFFE Then Return SetError(0xFFFE, -1, $vOut)

    If $eFQ <> $eFQ_Create Then
        If Not IsArray($aQ) Or $iSlots < 2 Then
            $iErr = 1 ;Queue not initialized
        ElseIf IsDllStruct($aQ[$iSlots]) Then
            $tKey = $aQ[$iSlots] ;MQ_Create adds an extra Slot -- pos data is stored there..
            If DllStructGetData($tKey, 1, $eID) <> $IDInit Then $iErr += 2 ;Queue not initialized (BY MQ_Create)
            If BitXOR($iSlots, $IDInit) <> DllStructGetData($tKey, 1, $eiSlots) Then $iErr += 4 ;number of slots doesn't match
            $iPos = DllStructGetData($tKey, 1, $eiPos)
            $iItems = DllStructGetData($tKey, 1, $eiItems)
        EndIf
        If $iErr And $eFQ <> $eFQ_IsInit Then $eFQ = $_FQ_Error
    Else
        $iSlots = $aQ ;
        If $iSlots < 2 Then $iSlots = 10
        Local $a[$iSlots + 1]
        $tKey = DllStructCreate("USHORT keys[4]")

        DllStructSetData($tKey, 1, $IDInit, $eID)
        DllStructSetData($tKey, 1, BitXOR($iSlots, $IDInit), $eiSlots)
        $a[$iSlots] = $tKey
        $vOut = $a
        ;ConsoleWrite("Created Queue[" & $iSlots & "]" & @CRLF)
        Return SetError($iErr, $iSlots, $vOut)
    EndIf
    ;Circular Queue Logic
    Switch ($eFQ)
        Case $_FQ_Error
            ConsoleWrite("Queue Error: " & $iErr & @CRLF)
            Return SetError($iErr, 0, $vOut)
        Case $eFQ_Push
            If $iItems >= $iSlots Then Return False
            ;Rollover after last element
            $aQ[Mod($iItems + $iPos, $iSlots)] = $vOut
            $iItems += 1
        Case $eFQ_Peek
            If $iItems = 0 Then Return False
            $vOut = $aQ[$iPos]
            Return True ; Speed up peek
        Case $eFQ_Pop
            If $iItems = 0 Then Return False
            $vOut = $aQ[$iPos]
            $iPos += 1
            $iItems -= 1
        Case $eFQ_Redim
            If $vOut <= $iSlots or $iItems <> 0 Then Return False
            If $iItems = 0 Then $iPos = 0 ;Reset to empty
            $vOut += 10
            $aQ[$iSlots] = Default
            ReDim $aQ[$vOut + 1]
            $aQ[$vOut] = $tKey 
            DllStructSetData($tKey, 1, BitXOR($vOut, $IDInit), $eiSlots)
        Case $eFQ_Empty
            $iItems = 0
        Case $eFQ_IsEmpty
            Return ($iItems = 0)
        Case $eFQ_IsFull
            Return ($iItems >= $iSlots)
        Case $eFQ_Count
            Return SetExtended($iSlots, $iItems)
        Case $eFQ_IsInit
            Return ($iErr = 0)
        Case Else
            Return False
    EndSwitch

    $iPos = Mod($iPos, $iSlots) ;Rollover after last element
    DllStructSetData($tKey, 1, $iPos, $eiPos)
    DllStructSetData($tKey, 1, $iItems, $eiItems)
    Return SetError($iErr, $iItems, True)
EndFunc   ;==>FifoQueue

;--Convenience Functions-------------------------------
Func FifoQueue_Create($iSlots = 10)
    Local $aE
    Return FifoQueue($eFQ_Create, $iSlots, $aE)
EndFunc   ;==>FifoQueue_Create

Func FifoQueue_($eFQ, ByRef $aQ)
    Local $aE
    $aE = FifoQueue($eFQ, $aQ, $aE)
    Return SetError(@error, @extended, $aE)
EndFunc   ;==>FifoQueue_
;--Convenience Functions-------------------------------

 

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Chimp
      This is a simple implementation of two stacks, one of FIFO type and the other of LIFO type.

      Both are based on the script.dictionary object and are self contained in two functions.
      If you call the function by passing an element as a parameter, that element is pushed on the stack,
      if you call the function without parameters, an element is retrieved (and removed) from the stack.
      both functions are used in the same way, the only difference is the order in which the data is returned, that is
      First In First Out for the _FIFO() function
      Last In First Out for the _LIFO() function
      here the two functions in its simplest form just to better see how they work. (see below for another version and example of use)
      Func _FIFO($vItem = '') Static Local $oFIFOStack = ObjCreate("Scripting.Dictionary") Static Local $iNDX = 1 Local $vPull = '' If $vItem = '' Then ; no Item to push, just pull from stack then If $oFIFOStack.Count Then ; ensure stack is not empty $vPull = $oFIFOStack.Item($iNDX) ; get the first item still in stack $oFIFOStack.Remove($iNDX) ; remove item from stack $iNDX += 1 ; raise the bottom index Return SetError(0, $oFIFOStack.Count, $vPull) ; return item to caller Else Return SetError(1, 0, '') EndIf Else $oFIFOStack.ADD($oFIFOStack.Count + $iNDX, $vItem) ; Add item SetExtended($oFIFOStack.Count) EndIf EndFunc ;==>_FIFO Func _LIFO($vItem = '') Static Local $oLIFOStack = ObjCreate("Scripting.Dictionary") Local $vPull = '' If $vItem = '' Then ; no Item to stack, just pull from stack then If $oLIFOStack.Count Then ; ensure stack is not empty $vPull = $oLIFOStack.Item($oLIFOStack.Count) ; get the top item $oLIFOStack.Remove($oLIFOStack.Count) ; remove item from stack Return SetError(0, $oLIFOStack.Count, $vPull) ; return item to caller Else Return SetError(1, 0, '') EndIf Else $oLIFOStack.ADD($oLIFOStack.Count + 1, $vItem) ; Add item SetExtended($oLIFOStack.Count) EndIf EndFunc ;==>_LIFO for a more convenient way of use, here below, there is a version that allows a  way to get the Count property, and to perform the RemoveAll method by the use of  an optional second parameter. See function header for more infos
      Have fun
      ; Example of FIFO stack: data keeps same order ConsoleWrite('FIFO example' & @CRLF & 'Push Data' & @CRLF) For $i = 1 To 50 ConsoleWrite($i & ' ') _FIFO($i) ; push $i in the stack Next ConsoleWrite(@CRLF & 'Pull Data' & @CRLF) For $i = 1 To _FIFO('', 3) ; _FIFO('', 3) return Count ConsoleWrite(_FIFO() & ' ') ; pull data & print it Next ; Example of LIFO stack: data returned in reverted order ConsoleWrite(@CRLF & @CRLF & 'LIFO example' & @CRLF & 'Push Data' & @CRLF) For $i = 1 To 50 ConsoleWrite($i & ' ') _LIFO($i) ; push $i in the stack Next ConsoleWrite(@CRLF & 'Pull Data' & @CRLF) For $i = 1 To _LIFO('', 3) ; _LIFO('', 3) return Count ConsoleWrite(_LIFO() & ' ') ; pull data & print it Next ConsoleWrite(@CRLF & @CRLF) ; #FUNCTION# ==================================================================================================================== ; Name ..........: _FIFO ; Description ...: A simple implementation of a FIFO stack (can be used to pull or push data from/to the stack) ; ; Syntax ........: _FIFO([$vItem = ''[, $vServiceCall = False]]) ; Parameters ....: $vItem - [optional] A variant value. Default is ''. ; this parameter can be empty or filled with data and behaves like: ; - if empty: the function pulls and return data from the stack ; - if filled: the function push that data to te stack ; $vServiceCall - [optional] A KeyWord or a value. Default is False. ; this parameter allows to perform some internal "methods" ; Note: When this parameter is used the previous parameter $vItem is simply ignored. ; 'Default' or 1 : Reindex the Key Names starting from 1 (internal use) ; 'Null' or 2 : Remove all items from the stack ; 'True' or 3 : Returns only the number of elements stored in the stack (returns 0 if stack is empty) ; ; Return values .: - when the function is used to Push data: ; returns nothing ; set @extended with the new total number of elements in the stack ; - when the function is used to Pull data: ; returns the pulled data (and removes it from the stack) ; set @extended with the number of elements still in the stack. ; If you try to pull data from an empty stack you get an empty string and @error is set to 1 ; ; Author ........: Chimp (Gianni Addiego) ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: ; =============================================================================================================================== Func _FIFO($vItem = '', $vServiceCall = False) Static Local $oFIFOStack = ObjCreate("Scripting.Dictionary") Static Local $iNDX = 1, $KEYWORD_DEFAULT = 1, $KEYWORD_NULL = 2, $KEYWORD_True = 3 Local $vPull = '' If $vServiceCall Or IsKeyword($vServiceCall) Then ; check second parameter Local $iService = IsKeyword($vServiceCall) ? IsKeyword($vServiceCall) : $vServiceCall ; Default = 1, Null = 2 If String($vServiceCall) = "True" Then $iService = $KEYWORD_True Switch $iService Case $KEYWORD_DEFAULT ; 1 or 'Default' Keyword was passed ; we use the Default Keyword to "normalize" all keys index starting from 1 If $oFIFOStack.Count Then Local $aKeys = $oFIFOStack.keys For $i = 0 To UBound($aKeys) - 1 $oFIFOStack.key($aKeys[$i]) = $i + 1 Next $iNDX = 1 EndIf Return SetExtended($oFIFOStack.Count) Case $KEYWORD_NULL ; 2 or 'Null' Keyword was passed WARNING: the stack is being emptied ; we use the Null KeyWord or value 2 to remove all items from the stack $oFIFOStack.RemoveAll Return SetExtended($oFIFOStack.Count) Case $KEYWORD_True ; 3 or 'True' Keyword was passed just return items count Return SetExtended($oFIFOStack.Count, $oFIFOStack.Count) Case Else ; Return SetError(0, $oFIFOStack.Count, $oFIFOStack.Count) Return SetError(1, $oFIFOStack.Count) EndSwitch EndIf If $vItem = '' Then ; no Item to stack, just pull from stack then If $oFIFOStack.Count Then ; ensure stack is not empty $vPull = $oFIFOStack.Item($iNDX) ; get the first item still in stack $oFIFOStack.Remove($iNDX) ; remove item from stack $iNDX += 1 ; raise the bottom index Return SetError(0, $oFIFOStack.Count, $vPull) ; return item to caller Else Return SetError(1, 0, '') EndIf Else $oFIFOStack.ADD($oFIFOStack.Count + $iNDX, $vItem) ; Add item SetExtended($oFIFOStack.Count) EndIf EndFunc ;==>_FIFO ; #FUNCTION# ==================================================================================================================== ; Name ..........: _LIFO ; Description ...: A simple implementation of a LIFO stack (can be used to pull or push data from/to the stack) ; ; Syntax ........: _LIFO([$vItem = ''[, $vServiceCall = False]]) ; Parameters ....: $vItem - [optional] A variant value. Default is ''. ; this parameter can be empty or filled with data and behaves like: ; - if empty: the function pulls and return data from the stack ; - if filled: the function push that data to te stack ; $vServiceCall - [optional] A KeyWord or a value. Default is False. ; this parameter allows to perform some internal "methods" ; Note: When this parameter is used the previous parameter $vItem is simply ignored. ; 'Null' or 2 : Remove all items from the stack ; 'True' or 3 : Return the number of elements stored in the stack (returns 0 if stack is empty) ; When this parameter is used the previous parameter $vItem is simply ignored. ; ; Return values .: - when the function is used to Push data: ; returns nothing ; set @extended with the new total number of elements in the stack ; - when the function is used to Pull data: ; returns the pulled data (and removes it from the stack) ; set @extended with the number of elements still in the stack. ; If you try to pull data from an empty stack you get an empty string and @error is set to 1 ; ; Author ........: Chimp (Gianni Addiego) ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: ; =============================================================================================================================== Func _LIFO($vItem = '', $vServiceCall = False) Static Local $oLIFOStack = ObjCreate("Scripting.Dictionary") Static Local $KEYWORD_DEFAULT = 1, $KEYWORD_NULL = 2, $KEYWORD_True = 3 Local $vPull = '' ; check if second parameter is used If $vServiceCall Or IsKeyword($vServiceCall) Then Local $iService = IsKeyword($vServiceCall) ? IsKeyword($vServiceCall) : $vServiceCall ; Default = 1, Null = 2 If String($vServiceCall) = "True" Then $iService = $KEYWORD_True ; True = 3 Switch $iService Case $KEYWORD_DEFAULT ; 1 or 'Default' Keyword was passed Return SetExtended($oLIFOStack.Count) Case $KEYWORD_NULL ; 2 or 'Null' Keyword was passed WARNING: the stack is being emptied ; we use the Null KeyWord or value 2 to remove all items from the stack $oLIFOStack.RemoveAll Return SetExtended($oLIFOStack.Count) Case $KEYWORD_True ; 3 or 'True' Keyword was passed just return items count Return SetExtended($oLIFOStack.Count, $oLIFOStack.Count) Case Else ; Return SetError(0, $oFIFOStack.Count, $oFIFOStack.Count) Return SetError(1, $oLIFOStack.Count) EndSwitch EndIf If $vItem = '' Then ; no Item to stack, just pull from stack then If $oLIFOStack.Count Then ; ensure stack is not empty $vPull = $oLIFOStack.Item($oLIFOStack.Count) ; get the top item $oLIFOStack.Remove($oLIFOStack.Count) ; remove item from stack Return SetError(0, $oLIFOStack.Count, $vPull) ; return item to caller Else Return SetError(1, 0, '') EndIf Else $oLIFOStack.ADD($oLIFOStack.Count + 1, $vItem) ; Add item SetExtended($oLIFOStack.Count) EndIf EndFunc ;==>_LIFO  
    • By Smitro
      Hi all,

      I'm in the middle of writing a print queue monitor. I would like to be able to run this on our print server to be able to track who's printing large amounts and reduce the effect on the environment.

      I've done a fair chunck of it, but I'm finding that it's causing a bit of a load on the CPU. On average the 'spoolsv.exe' process sits at about 15-20% constantly when nothing is happening. I'm wondering if there is a way I can reduce this.

      I'm using the following code to access the print queue.


      ; Connect to Print Queue $objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2") While 1 $AllPrintJobs = $objWMIService.ExecQuery ("SELECT * FROM Win32_PrintJob") ; Run through Print Jobs For $PrintJob In $AllPrintJobs ; Process any new jobs here Next Sleep (50) WEnd
      I've found that I have to catch the job several times in the queue. If I don't I can miss the total number of pages as the jobs spools.

      Is there another way of me getting the same information? Does the information go to another location after the print queue?
×
×
  • Create New...