Results 1 to 2 of 2

Thread: Storing a huge array on disk - paging in and out of memory

Threaded View

  1. #1

    Thread Starter
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Storing a huge array on disk - paging in and out of memory

    We had a thread back a couple of weeks ago where someone wanted to store a truly large array - one too large for memory and stack space in VB.

    This code shows an example of how to store an ARRAY of DOUBLE's on disk. It cannot be used for string arrays - as the len of each string is not fixed - while the length of a DOUBLE is always 8 bytes in memory (for instance).

    This is the variable declarations
    Code:
    Public b1 As Long, b2 As Long, b3 As Long
    ' Use these to retain the "bounds" of our array
    
    Private Type UDT_Array
        WA(999) As Double
    End Type
    ' This is our work array - we will page into
    ' memory from the disk 1000 doubles at a time
    
    Private dblPage As UDT_Array
    ' This is our current page
    
    Private CurWorkRecord As Long
    ' This will retain the "current" page in memory
    This is the function that "dimensions" the array. Basically writes a "zero-value" into each array spot and writes those pages to disk.
    Code:
    Private Function DimArray(x1 As Integer, x2 As Integer, x3 As Integer)
    
    Dim i As Long
    
    b1 = x1
    b2 = x2
    b3 = x3
    ' Retain the bounds that were passed
    
    Open "C:\ArraySpace.tmp" For Random As #1 Len = LenB(dblPage)
    ' Create the RANDOM access disk file with page size to match our work array
    
    For i = 1 To (b1 * b2 * b3) / 1000
        Put #1, i, dblPage
    Next i
    ' Initialize the disk file to all zeroes
    
    CurWorkRecord = -1
    ' Mark as "no current work record" paged
    
    End Function
    This is the actual array function itself - you can both "read" from this function or "write" to this function.
    Code:
    Private Function MyArray(x1 As Integer, x2 As Integer, x3 As Integer _
                                            , booSet As Boolean, dblValue As Double) As Double
    
    ' booSet as false will return a value from x1, x2, x3
    ' booSet as true will set the value at x1, x2, x3 to the dblValue passed
    
    Dim WorkSlot As Long, WorkRecord As Long
    
    WorkSlot = Location(x1, x2, x3) - 1
    ' Turn the x1, x2, x3 into a single-bound location
    
    WorkRecord = WorkSlot \ 1000
    ' Divide by 1000 to find out what page that slot is in
    
    WorkRecord = WorkRecord + 1
    ' Add 1 since the division will return 0 for the first 1000 slots
    
    If CurWorkRecord <> WorkRecord Then     ' We need a fresh read from disk
        If CurWorkRecord <> -1 Then         ' We need to write record back to disk
            Put #1, CurWorkRecord, dblPage
        End If
        Get #1, WorkRecord, dblPage         ' Now get the page we need
        CurWorkRecord = WorkRecord          ' And remember what page is in memory
    End If
    
    If booSet Then                          ' Set the value
        dblPage.WA(WorkSlot - ((WorkRecord - 1) * 1000)) = dblValue
        Debug.Print "Let's change the values at location "; x1; " "; x2; " "; x3; " to "; dblValue
        Debug.Print "Really at slot "; WorkSlot - ((WorkRecord - 1) * 1000); " in record "; CurWorkRecord
    Else                                    ' Return the value
        Debug.Print "Let's return the value from "; x1; " "; x2; " "; x3
        Debug.Print "Really at slot "; WorkSlot - ((WorkRecord - 1) * 1000); " in record "; CurWorkRecord
        MyArray = dblPage.WA(WorkSlot - ((WorkRecord - 1) * 1000))
    End If
    
    End Function
    This function simply turns the 3 dimension array location into a single line location.
    Code:
    Private Function Location(x1 As Integer, x2 As Integer, x3 As Integer) As Long
    
    ' 1000 x 500 x 200 is the array size
    
    ' 1st double is for 0,0,0
    ' 2nd double is for 0,0,1
    ' 201st double is for 0,0,200
    
    ' 202nd double is for 0,1,0
    ' 203rd double is for 0,1,1
    ' 402nd double is for 0,1,200
    
    ' 403rd double is for 0,2,0
    ' .
    ' .
    ' 201 for each x3
    ' repeated 501 times for each x2
    ' 201 * 501 = 100701 spots x1 = 0
    '
    ' 100702 spot is for 1,0,0
    
    Location = (x1 * ((b2 + 1) * (b3 + 1))) + (x2 * (b3 + 1)) + x3 + 1
    
    End Function
    Here is a test of the process itself
    Code:
    Private Sub Form_Load()
    
    Dim SomeDouble As Double
    
    Call DimArray(100, 500, 200)
    ' This dimensions our array on disk
    
    Call MyArray(1, 2, 3, True, 999.111)        ' Set a value
    
    SomeDouble = MyArray(1, 2, 3, False, 0)     ' Return a value
    
    Debug.Print SomeDouble
    
    Debug.Print "This just tested setting and returning a value at 1,2,3"
    Debug.Print ""
    
    Call MyArray(100, 500, 200, True, 888.222)      ' Set a value
    
    SomeDouble = MyArray(100, 500, 200, False, 0)   ' Return a value
    
    Debug.Print SomeDouble
    
    Debug.Print "This just tested setting and returning a value at 100,500,200"
    Debug.Print ""
    
    SomeDouble = MyArray(1, 2, 3, False, 0)         ' Return a value
    
    Debug.Print SomeDouble
    
    Debug.Print "This just tested regetting the value from 1,2,3"
    Debug.Print "This proves that we are properly paging the work array"
    
    End Sub
    When it's run this is the output in the immediate window testing it

    Code:
    Let's change the values at location  1   2   3  to  999.111 
    Really at slot  106  in record  102 
    Let's return the value from  1   2   3 
    Really at slot  106  in record  102 
     999.111 
    This just tested setting and returning a value at 1,2,3
    
    Let's change the values at location  100   500   200  to  888.222 
    Really at slot  800  in record  10171 
    Let's return the value from  100   500   200 
    Really at slot  800  in record  10171 
     888.222 
    This just tested setting and returning a value at 100,500,200
    
    Let's return the value from  1   2   3 
    Really at slot  106  in record  102 
     999.111 
    This just tested regetting the value from 1,2,3
    This proves that we are properly paging the work array
    Bluerose took these examples and put together a nice class that uses these concepts. Here is the zip file.

    Here is the thread post where Bluerose uploaded the zip - if you wanted to see the rest of this

    http://www.vbforums.com/showpost.php...4&postcount=49
    Attached Files Attached Files
    Last edited by szlamany; Jan 15th, 2008 at 03:50 AM.

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width