Fast text search (hash table / GLib)

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Re: Fast text search (hash table / GLib)

Post by TJF »

@ItemID(Counter) is a pointer to the STRING descriptor. Instead SADD(ItemID(Counter)) returns a ZSTRING PTR to the content of the STRING. I guess your code should look like

Code: Select all

'Fast text search (hash table / GLib)
'by TJF ≫ Sep 26, 2011 12:16
'https://www.freebasic.net/forum/viewtopic.php?f=7&t=18558&p=163893&hilit=glib+hash#p163893

' See for details
' http://developer.gnome.org/glib/2.28/glib-Hash-Tables.html

#INCLUDE ONCE "glib.bi"

DIM SHARED ItemID() AS STRING
DIM SHARED AS INTEGER Counter, i, j, k
DIM AS SINGLE t1,t2
DIM collisions AS INTEGER
DIM accumulation AS INTEGER


' ***** main / Hauptprogramm *****

' Create new hash table / Neue HashTable erstellen
' ★新しいハッシュテーブルを作成★
' g_hash_table_new (GHashFunc hash_func, GEqualFunc key_equal_func)
'                            演算子 @ (のアドレス)
' g_str_hash (gconstpointer v) 文字列をハッシュ値に変換します。
' g_str_equal (gconstpointer v1, gconstpointer v2) 2つの文字列をバイト毎に比較して、等しい場合は TRUE を返します。

VAR ArrayItemID = g_hash_table_new(@g_str_hash(), @g_str_equal())

t1=TIMER
Counter = 0
collisions = 0
accumulation = 0
' Insert keys and values / Fuellen mit den Keys und Values
' ★キーと値を挿入★

g_hash_table_insert(ArrayItemID, @!"AAC\0", GINT_TO_POINTER(987654))
g_hash_table_insert(ArrayItemID, @!"ZAC\0", GINT_TO_POINTER(876543))

FOR i = ASC("A") TO ASC("Z")
  FOR j = ASC("A") TO ASC("Z")
    FOR k = ASC("A") TO ASC("Z")
      Counter = UBOUND(ItemID) + 1
      REDIM PRESERVE ItemID(Counter)

      ItemID(Counter) = CHR(i, j, k, 0)
      IF g_hash_table_lookup(ArrayItemID, SADD(ItemID(Counter))) = 0 THEN
        accumulation = accumulation + 1
        g_hash_table_insert(ArrayItemID, SADD(ItemID(Counter)), GINT_TO_POINTER(Counter + 1000))
      ELSE
       'Display when duplicate keys occur
       collisions += 1
       PRINT g_hash_table_lookup(ArrayItemID, SADD(ItemID(Counter))) , Counter, ItemID(Counter)
      END IF
    NEXT k
  NEXT j
NEXT i

t2=TIMER

PRINT
PRINT
PRINT "Finished. Last ItemID = "; ItemID(Counter); "      Counter = 26^3(17,576) = "; Counter
PRINT "collisions = ";collisions," accumulation = ";accumulation
PRINT
PRINT "Required seconds = ";t2 - t1

' Destroy table, release memory / Tabelle aufloesen, Speicher freigeben
' テーブルを破棄、メモリを解放
g_hash_table_unref(ArrayItemID)

SLEEP
Regards
Makoto WATANABE
Posts: 232
Joined: Apr 10, 2010 11:41
Location: Japan
Contact:

Re: Fast text search (hash table / GLib)

Post by Makoto WATANABE »

Dear TJF;

Thanks for your quick reply.

> g_hash_table_insert(ArrayItemID, @!"AAC\0", GINT_TO_POINTER(987654))
Thank you for anticipating the pitfalls I would fall into next and teaching me the syntax.

I was able to run my program that checks for hash data collisions.
I increased the number of keys to 456,976 but it completed in about 2 seconds without collision.
"Fast text search" is very fast !!

Thank you very much.

Code: Select all

'Fast text search (hash table / GLib)
'by TJF ≫ Sep 26, 2011 12:16 
'https://www.freebasic.net/forum/viewtopic.php?f=7&t=18558&p=163893&hilit=glib+hash#p163893

' See for details
' http://developer.gnome.org/glib/2.28/glib-Hash-Tables.html

#Include Once "glib.bi"

Dim Shared ItemID() As String     
Dim Shared As Integer Counter, i, j, k, l
Dim As Single t1,t2
Dim collisions As Integer
Dim accumulation As Integer


' ***** main / Hauptprogramm *****

' Create new hash table / Neue HashTable erstellen
' ★新しいハッシュテーブルを作成★
' g_hash_table_new (GHashFunc hash_func, GEqualFunc key_equal_func)
'                            演算子 @ (のアドレス)
' g_str_hash (gconstpointer v) 文字列をハッシュ値に変換します。
' g_str_equal (gconstpointer v1, gconstpointer v2) 2つの文字列をバイト毎に比較して、等しい場合は TRUE を返します。

Var ArrayItemID = g_hash_table_new(@g_str_hash, @g_str_equal)

t1=Timer
Counter = 0
collisions = 0
accumulation = 0

' Insert keys and values / Fuellen mit den Keys und Values
' ★キーと値を挿入★

'g_hash_table_insert(ArrayItemID, @!"AAC\0", GINT_TO_POINTER(987654))
'g_hash_table_insert(ArrayItemID, @!"ZAC\0", GINT_TO_POINTER(876543))

For i = Asc("A") To Asc("Z")
   Print i;
   For j = Asc("A") To Asc("Z")
      For k = Asc("A") To Asc("Z")
         For l = Asc("A") To Asc("Z")
            Counter = Counter + 1
            ReDim Preserve ItemID(Counter + 1)
            
            'ItemID(Counter) =  Chr(i) + Chr(j) + Chr(k) + Chr(l)
            ItemID(Counter) = Chr(i, j, k, l)
            
            'SAdd(ItemID(Counter)) returns a ZSTRING PTR to the content of the STRING.
            If g_hash_table_lookup(ArrayItemID, SAdd(ItemID(Counter))) = 0 Then
               accumulation = accumulation + 1
               'g_hash_table_insert (GHashTable *hash_table, gpointer key, gpointer value)
               'GLib には、int から gpointer へ正確にキャストする GINT_TO_POINTER というマクロと、
               'gpointer から int へ正確にキャストする GPOINTER_TO_INT というマクロが定義されています。
               g_hash_table_insert(ArrayItemID, SAdd(ItemID(Counter)), GINT_TO_POINTER(Counter))
            Else
               'キーの重複が発生したら表示する
               'Display when duplicate keys occur
               collisions += 1
               Print
               Print g_hash_table_lookup(ArrayItemID, SAdd(ItemID(Counter))) , Counter, ItemID(Counter)
               Sleep
            End If
         Next l
      Next k
   Next j
Next i

t2=Timer

Print
Print
Print ItemID(accumulation) ,g_hash_table_lookup(ArrayItemID, SAdd(ItemID(accumulation)))
    
Print

'Print "終了しました。 ItemID = "; ItemID(Counter); "      Counter = 26^4(456,976) = "; Counter
Print "Finished. Last ItemID = "; ItemID(Counter); "      Counter = 26^4(456,976) = "; Counter
Print "collisions = ";collisions," accumulation = ";accumulation
Print
'Print "所要秒数 = ";t2 - t1
Print "Required seconds = ";t2 - t1

' Destroy table, release memory / Tabelle aufloesen, Speicher freigeben
' テーブルを破棄、メモリを解放
g_hash_table_unref(ArrayItemID)

Sleep
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Re: Fast text search (hash table / GLib)

Post by TJF »

Makoto WATANABE wrote:I was able to run my program that checks for hash data collisions.
I increased the number of keys to 456,976 but it completed in about 2 seconds without collision.
"Fast text search" is very fast !!
REDIM of array ItemID takes some time. If you want to check the poor hash table speed, you should fill that array first, and afterwards start to test the hash table operations.

Regards
Provoni
Posts: 514
Joined: Jan 05, 2014 12:33
Location: Belgium

Re: Fast text search (hash table / GLib)

Post by Provoni »

Makoto WATANABE wrote: Dear Provoni;
I want to implement an associative array.
Why do you need that? What are you planning to do?
Makoto WATANABE
Posts: 232
Joined: Apr 10, 2010 11:41
Location: Japan
Contact:

Re: Fast text search (hash table / GLib)

Post by Makoto WATANABE »

Dear Provoni;

I use an associative array to match item orders to a item master.
The program below collates the order of 50,000 items with the item master of 15,000 items and totals the order amount for each item.

For this degree of quantity, I think that using Excel macro will make a easier system to use, including pre-processing and post-processing ;-)

region.txt

Code: Select all

Alaska
Alabama
Arkansas
Arizona
California
Colorado
Connecticut
District of Columbia
Delaware
Florida
Georgia
Hawaii
Iowa
Idaho
Illinois
Indiana
Kansas
Kentucky
Louisiana
Massachusetts
Maryland
Maine
Michigan
Minnesota
Missouri
Mississippi
Montana
North Carolina
North Dakota
Nebraska
New Hampshire
New Jersey
New Mexico
Nevada
New York
Ohio
Oklahoma
Oregon
Pennsylvania
Rhode Island
South Carolina
South Dakota
Tennessee
Texas
Utah
Virginia
Vermont
Washington
Wisconsin
West Virginia
Wyoming
PrepareTestData01.bas

Code: Select all

'Prepare test Data

Dim Shared Counter As Integer
Dim Shared ItemID As String
Dim STARTT As Long
Dim ENDTIME As Long
Dim Minut As Integer


Sub FabricateData()
   
   Dim RegionArray() As String
   Dim file_name As String 
   Dim file_num As Integer
   Dim FirstDigit As Integer
   Dim SecondDigit As Integer
   Dim ThirdDigit As Integer
   Dim CharacterString As String
   Dim Regions As Integer

   'Fabricate ItemMaster
   
   file_name = "region.txt"
   file_num = FreeFile( )                 '' 有効なファイル番号を検索します
   Regions = 0

   '' ファイルを開きます。そして、ファイル番号をそれに結び付けます。エラーが有れば、抜けます。
   If( Open( file_name For Input As #file_num ) ) Then
      Print "ERROR: 開こうとしたファイル名 " ; file_name
      Sleep
      End -1
   End If

   Do Until EOF( file_num )               '' ファイルの端に達するまで、繰り返します。
      Regions = Regions + 1
      ReDim Preserve RegionArray(Regions)
      Line Input #file_num, RegionArray(Regions)           '' テキストの行を読みます。
      Print RegionArray(Regions)                           '' 画面にそれを出力します。
   Loop
               
   Close #file_num                        '' ファイル番号を通したファイルを閉じます。
   
   Open "ItemMaster.csv"  For Output As #1
   
   Counter = 0

   For FirstDigit = 1 To 26
      For SecondDigit = 1 To 26
         For ThirdDigit = 1 To 26
            CharacterString = ""
            Counter = Counter + 1
            If Counter > 15000 Then Exit For
            ItemID = Chr(64 + FirstDigit) & Chr(64 + SecondDigit) & Chr(64 + ThirdDigit) 'ItemID
            CharacterString = ItemID
            CharacterString = CharacterString & ",""" & RegionArray(Int(Rnd() * Regions) + 1)
            CharacterString = CharacterString & """," &  (Int(Rnd() * 1000) + 1) * 10    'price
            CharacterString = CharacterString & "," &  (Int(Rnd() * 100) + 1) * 10       'weight
            'Print CharacterString
            'Sleep
            Print #1, CharacterString
         Next ThirdDigit
      Next SecondDigit
   Next FirstDigit
   
   Close #1
   
   'Fabricate OrderList
   
   Open "OrderList.csv"  For Output As #1

   For Counter = 1 To 50000
      ItemID = Chr(64 + Int(Rnd() * 26) + 1) & Chr(64 + Int(Rnd() * 26) + 1) & Chr(64 + Int(Rnd() * 26) + 1)
      CharacterString = ItemID & "," & Int(Rnd() * 100) + 1               'quantity
      Print #1, CharacterString
   Next Counter
   
   Close #1
      
End Sub


STARTT=Val(Left(Time,2))*3600+Val(Mid(Time,4,2))*60+Val(Right(Time,2))

Randomize

FabricateData()

ENDTIME = Val(Left(Time,2))*3600+Val(Mid(Time,4,2))*60+Val(Right(Time,2))
Minut=(ENDTIME-STARTT)\60
Print
Print Using "Processing time was ## minutes ## seconds."; Minut; (ENDTIME-STARTT)-Minut*60
Print "*******************************************************"
Print "Please enter any key to exit."
Sleep
OrderSortingHashTable_glib01.bas

Code: Select all

'Fast text search (hash table / GLib)
'by TJF ≫ Sep 26, 2011 12:16 
'https://www.freebasic.net/forum/viewtopic.php?f=7&t=18558&p=163893&hilit=glib+hash#p163893

' See for details
' http://developer.gnome.org/glib/2.28/glib-Hash-Tables.html

#Include Once "glib.bi"                                  '★1★★★★★★★★★★★

' Create new hash table / Neue HashTable erstellen
' ★新しいハッシュテーブルを作成★
' g_hash_table_new (GHashFunc hash_func, GEqualFunc key_equal_func)
'                            演算子 @ (のアドレス)
' g_str_hash (gconstpointer v) 文字列をハッシュ値に変換します。
' g_str_equal (gconstpointer v1, gconstpointer v2) 2つの文字列をバイト毎に比較して、等しい場合は TRUE を返します。

Var MasterItemID = g_hash_table_new(@g_str_hash, @g_str_equal)  '★2★★★★★★★★★★★
Var OrderItemID = g_hash_table_new(@g_str_hash, @g_str_equal)   '★2★★★★★★★★★★★

Dim STARTT As Long
Dim ENDTIME As Long
Dim Minut As Integer
Dim Shared ItemID(20000) As String
Dim Shared OrderLine(20000) As String
Dim Shared OrderItem As String
Dim Shared Region As String
Dim Shared Price As String
Dim Shared Weight As String
Dim Shared Counter As Integer
Dim Shared collisions As Integer
Dim i As Integer
Dim QuantityString As String
Dim Amount As String
Dim Dimension As Integer
Dim cellString As String
   
Dim file_name As String 
Dim file_num As Integer
Dim CharacterString As String
Dim Regions As Integer
Dim ItemMasterNo As Integer
Dim IntegratedNo As Integer
Dim Orders As Integer

Dim Shared ItemMasterArray(20000,3) As String 'Region, price, weight
Dim Shared IntegratedOrderArray(20000,5) As String 'Region, ItemID, Quantity, Amount, Weight
Dim Shared SortArray(20000) As String

'****************************************************************
'****************************************************************

'★★★多次元配列を複数列を使ってソート★★★
'How to sort datasheet (x-dim array) by a few columns (at once in 1 loop) ?
'by badidea ≫ Dec 15, 2019 21:54 
'https://www.freebasic.net/forum/viewtopic.php?f=3&t=27993&start=30#p266914

'by fxm ≫ Jun 25, 2020 6:49 
'https://www.freebasic.net/forum/viewtopic.php?f=3&p=273475&sid=547977eb5d3cc9cf3e6ee7323616cff3#p273475

#Include "crt/stdlib.bi"
#Include "string.bi"

'------------------------------- class: row_type -------------------------------

Type row_type
   Dim As String col(Any)
   Declare Operator Cast () As String
End Type

Operator row_type.cast () As String
   Dim As String tempStr
   For i As Integer = 1 To UBound(col)
      If i = 1 Then tempStr &= col(i) Else tempStr &= !"\t" & col(i) 
   Next
   Return tempStr
End Operator

'------------------------------ class: sort_type -------------------------------

Type sort_type
   Dim As Short column
   Dim As Short direction
   Declare Constructor()
   Declare Constructor(column As Short, direction As Short)
End Type

'a stupid constructor
Constructor sort_type()
   this.column = 0
   this.direction = 0
End Constructor

'another stupid constructor
Constructor sort_type(column As Short, direction As Short)
   this.column = column
   this.direction = direction
End Constructor

'------------------------------ class: data_type -------------------------------

Type data_type
   Static As sort_type sortOrder(1 To 3)
   Dim As Integer numRows, numCols
   Dim As row_type row(Any)
   Declare Constructor(numRows As Integer, numPivotMS As Integer)
   Declare Destructor()
   Declare Sub copyTo(dst As data_type)
   Declare Sub sort(sort1st As sort_type, sort2nd As sort_type, sort3rd As sort_type)
   Declare Static Function qSortCallback Cdecl(pRow1 As row_type Ptr, pRow2 As row_type Ptr) As Long
End Type

Dim As sort_type data_type.sortOrder(1 To 3)

Constructor data_type(numRows As Integer, numCols As Integer)
   ReDim row(numRows)
   this.numCols = numCols
   For iRow As Integer = 1 To numRows
      ReDim (row(iRow).col)(numCols) 'weird syntax, compiler wants the extra ( )
   Next
End Constructor

Destructor data_type()
   For iRow As Integer = 1 To numRows
      Erase row(iRow).col
   Next
   Erase row
End Destructor

Sub data_type.sort(sort1st As sort_type, sort2nd As sort_type, sort3rd As sort_type)
   'disable invalid sort filters
   sortOrder(1) = IIf(sort1st.column < 1 Or sort1st.column >= numCols, sort_type(0,0), sort1st)
   sortOrder(2) = IIf(sort2nd.column < 1 Or sort2nd.column >= numCols, sort_type(0,0), sort2nd)
   sortOrder(3) = IIf(sort3rd.column < 1 Or sort3rd.column >= numCols, sort_type(0,0), sort3rd)
   qsort(@row(1), UBound(row), SizeOf(row_type), CPtr(Any Ptr, @qSortCallback))
End Sub

Function data_type.qSortCallback Cdecl(pRow1 As row_type Ptr, pRow2 As row_type Ptr) As Long
   For i As Integer = 1 To 3
      With sortOrder(i)
         Select Case .direction
         Case +1
            If pRow1->col(.column) < pRow2->col(.column) Then Return -1
            If pRow1->col(.column) > pRow2->col(.column) Then Return +1
         Case -1
            If pRow1->col(.column) > pRow2->col(.column) Then Return -1
            If pRow1->col(.column) < pRow2->col(.column) Then Return +1
         Case Else
            'skip, including direction = 0
         End Select
      End With
   Next
   Return 0
End Function


'****************************************************************
'****************************************************************
   Print "Read ""ItemMaster.csv"" and store each line in ItemMasterArray, indexing ItemID."
'****************************************************************
   Print
   
   file_name = "ItemMaster.csv"
   file_num = FreeFile( )                 '' 有効なファイル番号を検索します

   '' ファイルを開きます。そして、ファイル番号をそれに結び付けます。エラーが有れば、抜けます。
   If( Open( file_name For Input As #file_num ) ) Then
      Print "ERROR: 開こうとしたファイル名 " ; file_name
      Sleep
      End -1
   End If
   
   Counter = 0
   collisions = 0

   Do Until Eof( file_num )               '' ファイルの端に達するまで、繰り返します。
      Counter = Counter + 1   
      ItemID(Counter) ="": Region ="": Price ="" : Weight =""

      Line Input #file_num, CharacterString           '' テキストの行を読みます。
      
      ItemID(Counter) = Left(CharacterString,3)
      Region = Mid(CharacterString,6,InStrRev(CharacterString,"""")-6)
      Price  = Mid(CharacterString,InStrRev(CharacterString,"""")+2,InStrRev(CharacterString,",")-InStrRev(CharacterString,"""")-2)
      Weight = Right(CharacterString,Len(CharacterString)-InStrRev(CharacterString,","))

      If g_hash_table_lookup(MasterItemID, StrPtr(ItemID(Counter))) = 0 Then                   '★4★★★★★★★★★★★

         'g_hash_table_insert (GHashTable *hash_table, gpointer key, gpointer value)
         'GLib には、int から gpointer へ正確にキャストする GINT_TO_POINTER というマクロと、
         'gpointer から int へ正確にキャストする GPOINTER_TO_INT というマクロが定義されています。
         g_hash_table_insert(MasterItemID, StrPtr(ItemID(Counter)), GINT_TO_POINTER(Counter))  '★3★★★★★★★★★★★
         ItemMasterArray(Counter,1) = Region
         ItemMasterArray(Counter,2) = Price
         ItemMasterArray(Counter,3) = Weight   
      Else
         'キーの重複が発生したら表示する
         'Display when duplicate keys occur
         collisions += 1
         Print
         Print g_hash_table_lookup(MasterItemID, StrPtr(ItemID(Counter))) , Counter, ItemID(Counter)
         Sleep
      End If
      
   Loop
   Print "Numbers of Item Master = ";Counter
   Print 
   Print "Contents of the last Item Master : ";CharacterString  ' 画面に最終行を出力します。
   Print ItemID(Counter) , Region , Price ,  Weight 
   Print
   
   Close #file_num                        '' ファイル番号を通したファイルを閉じます。

'****************************************************************
'****************************************************************
   Print "Read ""OrderList.csv"" and compare it with ItemMasterArray to aggregate price and weight by item and region."
'****************************************************************
   Print
   
   Open "OrderItemError.csv"  For Output As #1

   file_name = "OrderList.csv"
   file_num = FreeFile( )                 '' 有効なファイル番号を検索します

   '' ファイルを開きます。そして、ファイル番号をそれに結び付けます。エラーが有れば、抜けます。
   If( Open( file_name For Input As #file_num ) ) Then
      Print "ERROR: 開こうとしたファイル名 " ; file_name
      Sleep
      End -1
   End If
   
   Counter = 0
   Orders  = 0
   
   STARTT=Val(Left(Time,2))*3600+Val(Mid(Time,4,2))*60+Val(Right(Time,2))

   Do Until Eof( file_num )               '' ファイルの端に達するまで、繰り返します。
      CharacterString = "" : OrderItem = "" : QuantityString = ""

      Line Input #file_num, CharacterString           '' テキストの行を読みます。
      Orders  = Orders + 1
      OrderItem = Left(CharacterString,3)
      QuantityString = Right(CharacterString,Len(CharacterString)-InStrRev(CharacterString,","))
      
      If g_hash_table_lookup(MasterItemID, StrPtr(OrderItem)) = 0 Then                   '★4★★★★★★★★★★★
         'Print OrderItem, g_hash_table_lookup(MasterItemID, StrPtr(OrderItem))
         'Sleep
      
         'エラー出力
         Print #1, CharacterString         
      Else
         
         ItemMasterNo = g_hash_table_lookup(MasterItemID, StrPtr(OrderItem))
         
         'ItemMasterArray(20000,3)      'Region, price, weight
         'IntegratedOrderArray(20000,5) 'Region, ItemID, Quantity, Amount, Weight
         
         Region = ItemMasterArray(ItemMasterNo,1)
         Amount = Str(Val(QuantityString)*Val(ItemMasterArray(ItemMasterNo,2)))
         Weight = Str(Val(QuantityString)*Val(ItemMasterArray(ItemMasterNo,3)))

         
         If g_hash_table_lookup(OrderItemID, StrPtr(OrderItem)) = 0 Then                   '★4★★★★★★★★★★★
            Counter = Counter + 1
            OrderLine(Counter) = OrderItem
            g_hash_table_insert(OrderItemID, StrPtr(OrderLine(Counter)), GINT_TO_POINTER(Counter)) '★3★★★★★★★★★★★

            IntegratedOrderArray(Counter,1) = Region
            IntegratedOrderArray(Counter,2) = OrderItem
            IntegratedOrderArray(Counter,3) = QuantityString
            IntegratedOrderArray(Counter,4) = Amount
            IntegratedOrderArray(Counter,5) = Weight
            'Print Counter,Region,ItemID,QuantityString,Amount,Weight
            'sleep
   
         Else
            IntegratedNo = g_hash_table_lookup(OrderItemID, StrPtr(OrderItem))
            
            IntegratedOrderArray(IntegratedNo,3) = Str(Val(IntegratedOrderArray(IntegratedNo,3))+Val(QuantityString))
            IntegratedOrderArray(IntegratedNo,4) = Str(Val(IntegratedOrderArray(IntegratedNo,4))+Val(Amount))
            IntegratedOrderArray(IntegratedNo,5) = Str(Val(IntegratedOrderArray(IntegratedNo,5))+Val(Weight))
            'Print IntegratedNo,ItemID,QuantityString,Amount,Weight
            'sleep
   
         End If
      End If
      
   Loop
   Print "Number of orders in the list : ";Orders
   Print
   ENDTIME = Val(Left(Time,2))*3600+Val(Mid(Time,4,2))*60+Val(Right(Time,2))
   Minut=(ENDTIME-STARTT)\60
   Print Using "processing time: ## minutes ## seconds"; Minut; (ENDTIME-STARTT)-Minut*60
   Print
   
   Close #1
   Close #file_num                        '' ファイル番号を通したファイルを閉じます。

'****************************************************************
'****************************************************************
' Destroy table, release memory / Tabelle aufloesen, Speicher freigeben
' テーブルを破棄、メモリを解放
g_hash_table_unref(MasterItemID)
g_hash_table_unref(OrderItemID)

'****************************************************************
'****************************************************************
   Print "Sort the totaled results by Region and ItemID."
'****************************************************************
   Print


Dim As Integer numRows = Counter, numCols = 5

Var myData = data_type(numRows, numCols)

For iRow As Integer = 1 To Counter
   With myData.row(iRow)
      For iCol As Integer = 1 To UBound(.col)
         .col(iCol) = IntegratedOrderArray(iRow,iCol)
      Next
   End With
Next iRow

myData.sort(sort_type(1, +1), sort_type(2, +1), sort_type(0, 0))

For iRow As Integer = 1 To Counter
   With myData.row(iRow)
      For iCol As Integer = 1 To UBound(.col)
         IntegratedOrderArray(iRow,iCol) = .col(iCol)
      Next
   End With
Next iRow


'****************************************************************
'****************************************************************
   Print "Out put the sorted results to ""OrderSorting.csv"""
'****************************************************************
   Print

   'IntegratedOrderArray(20000,5) 'Region, ItemID, Quantity, Amount, Weight
   Open "OrderSorting.csv"  For Output As #1
      For i = 1 To Counter
         CharacterString = ""
         For Dimension =1 To 5
            cellString = IntegratedOrderArray(i,Dimension)
            If Dimension = 1 Then
               cellString = """" & cellString & """"
            EndIf
            If Dimension > 1 Then
               cellString = "," & cellString
            EndIf
            CharacterString = CharacterString & cellString
         Next Dimension

         Print #1, CharacterString

      Next i
   Close #1
   

'****************************************************************
'****************************************************************
   Print "Output of the sorted order aggregate has been completed."
   Print "*******************************************************"
   Print "Please enter any key to exit."
   
Sleep
Post Reply