Click here to Skip to main content
15,892,005 members
Articles / Programming Languages / Visual Basic

Searching, Sorting, and Multitasking Comparisons

Rate me:
Please Sign up or sign in to vote.
4.19/5 (16 votes)
31 May 20049 min read 96K   1.9K   49  
Visually displays various searching and sorting techniques using different multitasking techniques.
'-------------------------------------------------
' Searching, Sorting, and Multitasking Comparisons
' 
' Written By Jeffrey B. Firestone
' Jeffrey B. Firestone Company
' jfirestone@jbfc.com
' 
' May 29, 2004
' 
' You may redistribute this control in binary and modified binary form as you please.  You may
' use this control in commercial applications without need for external credit royalty free.
' 
' However, you are restricted from releasing the source code in any modified fashion
' whatsoever.
' 
' I MAKE NO PROMISES OR WARRANTIES ON THIS CODE/CONTROL.  IF ANY DAMAGE OR PROBLEMS HAPPEN FROM ITS USE
' THEN YOU ARE RESPONSIBLE.

Option Strict On

Imports System.Windows.Forms
Imports VB = Microsoft.VisualBasic
Imports System.Random
Imports System.Data


Public Class HashtableCollection
    Implements IDisposable

    Private m_frmMain As frmMain
    Private m_IsInitialized As Boolean
    Private m_IsRunning As Boolean
    Private m_Hashtable As System.Collections.Hashtable
    Private m_iColumnNumber As Integer
    Private m_iRowNumber As Integer


#Region "Properties"
    Public ReadOnly Property ClassDescription() As String
        Get
            ClassDescription = "Hashtable Collection"
        End Get
    End Property

    Public Property frmMain() As Form
        Get
            frmMain = m_frmMain
        End Get
        Set(ByVal Value As Form)
            m_frmMain = CType(Value, frmMain)
        End Set
    End Property

    Public Property IsInitialized() As Boolean
        Get
            IsInitialized = m_IsInitialized
        End Get
        Set(ByVal Value As Boolean)
            m_IsInitialized = Value
        End Set
    End Property

    Public Property IsRunning() As Boolean
        Get
            IsRunning = m_IsRunning
        End Get
        Set(ByVal Value As Boolean)
            m_IsRunning = Value
        End Set
    End Property

    Public ReadOnly Property DataSize() As Integer
        Get
            If Not (m_Hashtable Is Nothing) Then
                DataSize = m_Hashtable.Count
            End If
        End Get
    End Property
#End Region


#Region "Publics"

    Public Function RunProc(ByVal iColumnNumber As Integer, ByVal iRowNumber As Integer) As String
        Dim strResults As String = ""

        IsRunning = True
        m_iColumnNumber = iColumnNumber
        m_iRowNumber = iRowNumber
        Select Case iColumnNumber
            Case 0 : ShowData()
            Case 1 : strResults = Create()
            Case 2 : strResults = DatasetScan()
            Case 3 : strResults = Find_1_Key_Field()
            Case 4 : strResults = Find_All_NonKey_Values()
            Case 5 : strResults = Find_n_Fields()
            Case 6 : strResults = Sort()
        End Select
        IsRunning = False

        Return strResults
    End Function

    Public Function Create() As String
        Dim t As Double = VB.Timer()

#If 1 Then
        ' The HashTable's internal management routines are optimized for a prime number
        ' of elements. So, where possible, create a new HashTable with a number of elements
        ' equaling  11, 53, 101, 503, 1009, 5003, 10007, etc.
        Dim lDataSize As Integer = GetNextPrime(m_frmMain.Data_Size)
#Else
        ' This is a bit slower
        Dim lDataSize As Integer = m_frmMain.Data_Size
#End If

        m_Hashtable = Nothing
        m_Hashtable = New System.Collections.Hashtable(lDataSize)

        For lCount As Integer = 0 To m_frmMain.Data_Size
            Dim oTestData As TestData.TestDataStructure = m_frmMain.TestData.arTestData(lCount)
            m_Hashtable.Add(oTestData.sUnique, oTestData)
        Next

        m_IsInitialized = True

        t = VB.Timer() - t
        Return CStr(IIf(m_frmMain.fCancel, ">", "")) & Format(t, "0.00")
    End Function

    Public Function DatasetScan() As String
        Dim lUnique As Integer
        Dim sUnique As String
        Dim lNonUnique As Integer
        Dim sNonUnique As String

        If Not m_IsInitialized Or DataSize <> m_frmMain.Data_Size Then Create()

        Dim t As Double = VB.Timer()

        Dim lScanRepeat As Integer = m_frmMain.Scan_Repeat
        For lScanCount As Integer = 0 To lScanRepeat
            If m_frmMain.rbDoEvents.Checked Then Application.DoEvents()
            If m_frmMain.fCancel Then Exit For
            If lScanCount Mod Math.Max(lScanRepeat \ 10,1) = 0 Then m_frmMain.UpdateProgress(m_iRowNumber, m_iColumnNumber, (lScanCount * 100) \ lScanRepeat)

            Dim e As System.Collections.IEnumerator = m_Hashtable.GetEnumerator()
            While e.MoveNext()
                With DirectCast(e.Current.Value, TestData.TestDataStructure)
                    lUnique = .lUnique
                    sUnique = .sUnique
                    lNonUnique = .lNonUnique
                    sNonUnique = .sNonUnique
                End With
            End While
            e = Nothing
        Next

        t = VB.Timer() - t
        Return CStr(IIf(m_frmMain.fCancel, ">", "")) & Format(t, "0.00")
    End Function

    Public Function Find_1_Key_Field() As String
        Dim s As String
        Dim sFind As String
        Dim lFind As Integer
        Dim rndGen As New System.Random

        If Not m_IsInitialized Or DataSize <> m_frmMain.Data_Size Then Create()

        Dim t As Double = VB.Timer()

        Dim lDataSize As Integer = m_frmMain.Data_Size
        Dim lFindRepeat As Integer = m_frmMain.Find_Repeat
        For lCount As Integer = 0 To lFindRepeat
            If m_frmMain.rbDoEvents.Checked Then Application.DoEvents()
            If m_frmMain.fCancel Then Exit For
            If lCount Mod Math.Max((lFindRepeat \ 10), 1) = 0 Then m_frmMain.UpdateProgress(m_iRowNumber, m_iColumnNumber, (lCount * 100) \ lFindRepeat)

            sFind = "Str" & CInt(rndGen.Next(lDataSize))
            Dim oData As TestData.TestDataStructure = DirectCast(m_Hashtable.Item(sFind), TestData.TestDataStructure)
            s = oData.sUnique
        Next

        t = VB.Timer() - t
        Return CStr(IIf(m_frmMain.fCancel, ">", "")) & Format(t, "0.00")
    End Function

    Public Function Find_All_NonKey_Values() As String
        Dim lFound As Integer
        Dim rndGen As New System.Random

        If Not m_IsInitialized Or DataSize <> m_frmMain.Data_Size Then Create()

        Dim t As Double = VB.Timer()

        Dim lDataSize As Integer = m_frmMain.Data_Size
        Dim lFindRepeat As Integer = m_frmMain.Find_Repeat
        For lCount As Integer = 0 To lFindRepeat
            If m_frmMain.rbDoEvents.Checked Then Application.DoEvents()
            If m_frmMain.fCancel Then Exit For
            If lCount Mod Math.Max((lFindRepeat \ 10), 1) = 0 Then m_frmMain.UpdateProgress(m_iRowNumber, m_iColumnNumber, (lCount * 100) \ lFindRepeat)

            Dim lFind As Integer = CInt(rndGen.Next(CInt(lDataSize / 10)))
            Dim e As System.Collections.IEnumerator = m_Hashtable.GetEnumerator()
            While e.MoveNext()
                With DirectCast(e.Current.Value, TestData.TestDataStructure)
                    If .lNonUnique = lFind Then
                        lFound = .lNonUnique
                    End If
                End With
            End While
        Next

        t = VB.Timer() - t
        Return CStr(IIf(m_frmMain.fCancel, ">", "")) & Format(t, "0.00")
    End Function

    Public Function Find_n_Fields() As String
        Dim s As String
        Dim sFind As String
        Dim lHits As Integer = 0
        Dim rndGen As New System.Random

        If Not m_IsInitialized Or DataSize <> m_frmMain.Data_Size Then Create()

        Dim t As Double = VB.Timer()

        Dim lDataSize As Integer = m_frmMain.Data_Size
        Dim lFindRepeat As Integer = m_frmMain.Find_Repeat
        For lCount As Integer = 0 To lFindRepeat
            If m_frmMain.rbDoEvents.Checked Then Application.DoEvents()
            If m_frmMain.fCancel Then Exit For
            If lCount Mod Math.Max((lFindRepeat \ 10), 1) = 0 Then m_frmMain.UpdateProgress(m_iRowNumber, m_iColumnNumber, (lCount * 100) \ lFindRepeat)

            sFind = "Str" & CInt(rndGen.Next(lDataSize))
            Dim oData As TestData.TestDataStructure = DirectCast(m_Hashtable.Item(sFind), TestData.TestDataStructure)
            With oData
                If StrComp(.sUnique, sFind, CompareMethod.Binary) = 0 AndAlso StrComp(.sNonUnique, "Second", CompareMethod.Binary) = 0 Then
                    lHits = lHits + 1
                    s = oData.sUnique
                End If
            End With
        Next

        t = VB.Timer() - t
        s = CStr(IIf(m_frmMain.fCancel, ">", "")) & Format(t, "0.00") & " (" & lHits & " recs)"
        Return s
    End Function

    Public Function Sort() As String
        If Not m_IsInitialized Or DataSize <> m_frmMain.Data_Size Then Create()

        Dim t As Double = VB.Timer()

        Dim aData(m_frmMain.Data_Size) As TestData.TestDataStructure
        m_Hashtable.Values.CopyTo(aData, 0)

        Dim oTestDataIComparer As New TestData.lNonUnique_IComparer
        System.Array.Sort(aData, oTestDataIComparer)
        oTestDataIComparer = Nothing

        Dim lUnique As Integer
        Dim sUnique As String
        Dim lNonUnique As Integer
        Dim sNonUnique As String
        For l As Integer = 0 To m_Hashtable.Count - 1
            Dim oData As TestData.TestDataStructure = DirectCast(m_Hashtable.Item(aData(l).sUnique), TestData.TestDataStructure)
            With oData
                lUnique = .lUnique
                sUnique = .sUnique
                lNonUnique = .lNonUnique
                sNonUnique = .sNonUnique
            End With
        Next

        t = VB.Timer() - t
        Return CStr(IIf(m_frmMain.fCancel, ">", "")) & Format(t, "0.00")
    End Function

    Public Function ShowData() As Boolean
        Dim frm As ShowData = New ShowData

        With frm.dt.Columns
            .Add(New DataColumn("lUnique", GetType(Integer)))
            .Add(New DataColumn("sUnique", GetType(String)))
            .Add(New DataColumn("lNonUnique", GetType(Integer)))
            .Add(New DataColumn("sNonUnique", GetType(String)))
        End With

        If Not (m_Hashtable Is Nothing) Then
            Dim e As System.Collections.IEnumerator = m_Hashtable.GetEnumerator()
            While e.MoveNext()
                With DirectCast(e.Current.Value, TestData.TestDataStructure)
                    Dim dr As DataRow
                    dr = frm.dt.NewRow
                    dr.BeginEdit()
                    dr.Item("lUnique") = .lUnique
                    dr.Item("sUnique") = .sUnique
                    dr.Item("lNonUnique") = .lNonUnique
                    dr.Item("sNonUnique") = .sNonUnique
                    dr.EndEdit()
                    frm.dt.Rows.Add(dr)
                End With
            End While
        End If

        With frm
            .dg.DataSource = .dt
            .Show()
            frm.Text = ClassDescription
        End With

    End Function
#End Region

#Region "Privates"
    ' Returns a prime number that is equal or greater than the given number
    Private Function GetNextPrime(ByVal baseNumber As Integer) As Integer
        Dim n As Integer = baseNumber
        ' Arguments : baseNumber - The starting number from which to compute the current or next prime
        ' Returns   : Current Number (if prime) or Next larger prime number

        If n Mod 2 = 0 Then n += 1
        Do Until IsNumberPrime(n) Or (n = n.MaxValue)
            n += 2
        Loop
        Return n
    End Function


    ' Determines if a number is a prime number
    Private Function IsNumberPrime(ByVal numberToCheck As Integer) As Boolean
        ' Arguments : numberToCheck - The number to check
        ' Returns   : True if the number is prime 
        '             False if the number is not prime

        Dim counter As Integer
        Dim test As Integer
        Dim limit As Integer
        Dim isPrime As Boolean

        ' Convert the number to a positive value
        test = System.Math.Abs(numberToCheck)

        Select Case test
            Case 0, 1
                isPrime = False

            Case 2
                isPrime = True

            Case Else
                If test Mod 2 = 0 Then
                    ' Even numbers are not prime.
                    isPrime = False
                Else
                    ' Odd numbers need to be tested.
                    ' Test if an odd number divides into the value
                    ' without a remainder. Test to square root of value.
                    isPrime = True
                    limit = CType((System.Math.Sqrt(test)) + 1, Integer)
                    For counter = 3 To limit Step 2
                        If test Mod counter = 0 Then
                            ' Number is not prime
                            isPrime = False
                            Exit For
                        End If
                    Next counter
                End If
        End Select

        Return isPrime

    End Function
#End Region

#Region "Dispose"
    Public Sub Dispose() Implements System.IDisposable.Dispose
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub

    Protected Overridable Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            ' Free dependent objects
            m_Hashtable = Nothing
        End If

        ' Free un-managed resources
        ' No managed resource here.
        ' Must be thread-safe here.

    End Sub

    Protected Overrides Sub Finalize()
        Dispose(False)
    End Sub
#End Region

End Class

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
I am a Houston, Texas based software developer and consultant specializing in .NET and database system development.

I work with SQL Server, Oracle, MySQL, along with VB6, C#, and VB.NET.

I have provided consulting services to companies in the Houston area and beyond for over twenty years.

I can be reached via jfirestone@jbfco.com

Comments and Discussions