KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derbyTesting > unitTests > store > T_SortController


1 /*
2
3    Derby - Class org.apache.derbyTesting.unitTests.store.T_SortController
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to You under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derbyTesting.unitTests.store;
23
24 // impl imports are the preferred way to create unit tests.
25
import org.apache.derbyTesting.unitTests.harness.T_Generic;
26 import org.apache.derbyTesting.unitTests.harness.T_Fail;
27
28 import org.apache.derby.iapi.store.access.*;
29
30 import org.apache.derby.iapi.services.context.ContextService;
31
32 import org.apache.derby.iapi.services.monitor.Monitor;
33 import org.apache.derby.iapi.services.io.Storable;
34
35 import org.apache.derby.iapi.error.StandardException;
36
37 import org.apache.derby.iapi.types.DataValueDescriptor;
38
39 import org.apache.derby.iapi.reference.Property;
40
41 import org.apache.derby.iapi.services.i18n.MessageService;
42
43 import org.apache.derby.iapi.reference.SQLState;
44
45 import org.apache.derby.iapi.types.SQLInteger;
46
47 import java.security.AccessController JavaDoc;
48 import java.security.PrivilegedAction JavaDoc;
49 import java.util.Properties JavaDoc;
50 import java.util.Vector JavaDoc;
51 import java.util.StringTokenizer JavaDoc;
52 import java.io.File JavaDoc;
53
54 /**
55
56   Unit test for sorting.
57
58 **/

59
60 public class T_SortController extends T_Generic
61 {
62     private static final String JavaDoc testService = "sortTest";
63
64     /** Set this to print out the rows that are inserted into
65      ** and returned from each sort. **/

66     protected boolean verbose = false;
67
68     public String JavaDoc getModuleToTestProtocolName() {
69         return AccessFactory.MODULE;
70     }
71
72     private void setSortBufferSize(final String JavaDoc buf_length) {
73         AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
74             public Object JavaDoc run() {
75                 System.setProperty("derby.storage.sortBufferMax", buf_length);
76                 return null;
77             }
78         });
79     }
80
81     /*
82     ** Methods of T_SortController
83     */

84
85     /**
86         @exception T_Fail test has failed
87     */

88     protected void runTests() throws T_Fail
89     {
90         int failcount = 0;
91
92         // Get the AccessFactory to test.
93

94         // don't automatic boot this service if it gets left around
95
if (startParams == null) {
96             startParams = new Properties JavaDoc();
97         }
98         startParams.put(Property.NO_AUTO_BOOT, Boolean.TRUE.toString());
99         // remove the service directory to ensure a clean run
100
startParams.put(Property.DELETE_ON_CREATE, Boolean.TRUE.toString());
101
102         // see if we are testing encryption
103
startParams = T_Util.setEncryptionParam(startParams);
104
105         try {
106             REPORT("(unitTestMain) Testing " + "sortTest with default sort buffer size 1024");
107             AccessFactory store1024 = null;
108             failcount = runEachTest(store1024, "1024");
109
110             setSortBufferSize("4");
111             REPORT("(unitTestMain) Testing " + "sortTest with minimum sort buffer size 4");
112             AccessFactory store4 = null;
113             failcount += runEachTest(store4, "4");
114         }
115         catch (StandardException e)
116         {
117             String JavaDoc msg = e.getMessage();
118             if (msg == null)
119                 msg = e.getClass().getName();
120             REPORT("(unitTestMain) unexpected exception: " + msg);
121             throw T_Fail.exceptionFail(e);
122         }
123
124         if (failcount != 0)
125             throw T_Fail.testFailMsg("(unitTestMain)" + failcount + " cases failed.");
126
127         REPORT("(unitTestMain) succeeded");
128     }
129
130     protected int runEachTest(AccessFactory store, String JavaDoc tail) throws T_Fail, StandardException {
131
132         TransactionController tc = null;
133         int failcount = 0;
134
135         try {
136             store = (AccessFactory) Monitor.createPersistentService(getModuleToTestProtocolName(),
137                 testService + tail, startParams);
138         } catch (StandardException mse) {
139             throw T_Fail.exceptionFail(mse);
140         }
141         if (store == null) {
142             throw T_Fail.testFailMsg(getModuleToTestProtocolName() + " service not started.");
143         }
144
145         tc = store.getTransaction(
146                 ContextService.getFactory().getCurrentContextManager());
147
148         if (!sortExample(tc))
149             failcount++;
150         if (!sortBufferCoverage(tc))
151             failcount++;
152         if (!sortBoundaries(tc))
153             failcount++;
154         if (!sortAllDuplicates(tc))
155             failcount++;
156         if (!sortDescending(tc))
157             failcount++;
158
159         tc.commit();
160         tc.destroy();
161
162         return failcount;
163     }
164
165     /**
166     This test is more of an example, with lots of comments to
167     explain what's going on.
168     **/

169     boolean sortExample(TransactionController tc)
170         throws StandardException
171     {
172         REPORT("(sortExample)");
173
174         // Create the rows to be sorted.
175
T_AccessRow row[] = new T_AccessRow[4];
176         row[0] = new T_AccessRow(18, 1, 2);
177         row[1] = new T_AccessRow( 6, 1, 18);
178         row[2] = new T_AccessRow(18, 1, 2);
179         row[3] = new T_AccessRow( 8, 14, 3);
180
181         // Decide on what kind of sort we want. The properties
182
// can select different sorting techniques and options.
183
// But all sorts will result in the rows being in order.
184
// We don't care which sort technique is used, so set
185
// the properties to null.
186
Properties JavaDoc implParameters = null;
187
188         // Define the type of rows to be sorted by constructing
189
// a template. Any row with the correct column types
190
// will do (the values in the template are never used,
191
// just the types). The first row to be inserted will
192
// make a good template.
193
T_AccessRow template = row[0];
194
195         // Define the column ordering: sort on column 1
196
// (the second column) ascending, then column 2
197
// (the third column) ascending.
198
ColumnOrdering order[] = new ColumnOrdering[2];
199         order[0] = new T_ColumnOrderingImpl(1, true); // ascending
200
order[1] = new T_ColumnOrderingImpl(2, true); // ascending
201

202         // Tell the sort that the rows are not already in order.
203
boolean alreadyInOrder = false;
204
205         // Tell the sort that we're estimating that about 10
206
// rows will be inserted into the sort. This is just
207
// a hint, the sort will still work if more rows or
208
// fewer rows are inserted. But if the guess is close
209
// the sort will probably run faster.
210
long estimatedRows = 10;
211
212         // Tell the sort that we're estimating that the rows
213
// are about 24 bytes long (3 int columns).
214
// This is just a hint, the sort will still work if rows of
215
// less or greater size are inserted. But if the guess is close
216
// the sort will probably run faster.
217
int estimatedRowSize = 12;
218
219         // Create the sort.
220
long sortid = tc.createSort(implParameters, template.getRowArray(),
221             order, new T_DuplicateEliminator(template), alreadyInOrder, estimatedRows,
222             estimatedRowSize);
223
224         // For the above sort, on the above input rows, we expect
225
// the output rows to look like this:
226
T_AccessRow expectedRow[] = new T_AccessRow[3];
227         expectedRow[0] = new T_AccessRow(18, 1, 2);
228         expectedRow[1] = new T_AccessRow( 6, 1, 18);
229         expectedRow[2] = new T_AccessRow( 8, 14, 3);
230
231         return testSort(tc, row, expectedRow, sortid);
232     }
233
234     /**
235     This test covers specific code paths in the external sort's
236     sort buffer. It really should live closer to the sort buffer
237     since the effectiveness of this test is very very implementation
238     dependent.
239     **/

240     boolean sortBufferCoverage(TransactionController tc)
241         throws StandardException
242     {
243         REPORT("(sortBufferCoverage)");
244
245         // Create the rows to be sorted. This sequence of values
246
// will provoke both single and double rotations on insert
247
// and both single and double rotations on removal. Every
248
// row has a duplicate so that we can test duplicate handling
249
// in every tree position and through all manipulations.
250
T_AccessRow row[] = new T_AccessRow[16];
251         row[0] = new T_AccessRow(2, 0, 0); // first node
252
row[1] = new T_AccessRow(2, 0, 0);
253
254         row[2] = new T_AccessRow(4, 0, 0); // This makes the tree get higher [A7 case (i)]
255
row[3] = new T_AccessRow(4, 0, 0);
256
257         row[4] = new T_AccessRow(1, 0, 0); // This makes the tree more balanced [A7 case (ii)]
258
row[5] = new T_AccessRow(1, 0, 0);
259
260         row[6] = new T_AccessRow(7, 0, 0); // Tree getting higher again [A7 case (i)]
261
row[7] = new T_AccessRow(7, 0, 0);
262
263         row[8] = new T_AccessRow(8, 0, 0); // Tree getting out of balance [A7 case iii]
264
// Single rotation will fix [A8]
265
row[9] = new T_AccessRow(8, 0, 0);
266
267         row[10] = new T_AccessRow(3, 0, 0); // Tree getting out of balance [A7 case iii]
268
// Double rotation will fix [A9]
269
row[11] = new T_AccessRow(3, 0, 0);
270
271         row[12] = new T_AccessRow(5, 0, 0); // Tree more balanced [A7 case (ii)]
272
row[13] = new T_AccessRow(5, 0, 0);
273
274         row[14] = new T_AccessRow(6, 0, 0); // Tree getting higher again [A7 case (i)]
275
row[15] = new T_AccessRow(6, 0, 0);
276
277         // RESOLVE (nat) Should select the sort that being tested here.
278
Properties JavaDoc implParameters = null;
279
280         T_AccessRow template = row[0];
281
282         // Sort on column 0 (the first column) ascending
283
ColumnOrdering order[] = new ColumnOrdering[1];
284         order[0] = new T_ColumnOrderingImpl(0, true); // ascending
285

286         // The rows are not already in order.
287
boolean alreadyInOrder = false;
288
289         long estimatedRows = 20;
290         int estimatedRowSize = 12;
291
292         // Create the sort.
293
long sortid = tc.createSort(implParameters, template.getRowArray(),
294             order, new T_DummySortObserver(template), alreadyInOrder, estimatedRows,
295             estimatedRowSize);
296
297         // Rows should come out in order
298
T_AccessRow expectedRow[] = new T_AccessRow[16];
299         expectedRow[0] = new T_AccessRow(1, 0, 0);
300         expectedRow[1] = new T_AccessRow(1, 0, 0);
301         expectedRow[2] = new T_AccessRow(2, 0, 0);
302         expectedRow[3] = new T_AccessRow(2, 0, 0);
303         expectedRow[4] = new T_AccessRow(3, 0, 0);
304         expectedRow[5] = new T_AccessRow(3, 0, 0);
305         expectedRow[6] = new T_AccessRow(4, 0, 0);
306         expectedRow[7] = new T_AccessRow(4, 0, 0);
307         expectedRow[8] = new T_AccessRow(5, 0, 0);
308         expectedRow[9] = new T_AccessRow(5, 0, 0);
309         expectedRow[10] = new T_AccessRow(6, 0, 0);
310         expectedRow[11] = new T_AccessRow(6, 0, 0);
311         expectedRow[12] = new T_AccessRow(7, 0, 0);
312         expectedRow[13] = new T_AccessRow(7, 0, 0);
313         expectedRow[14] = new T_AccessRow(8, 0, 0);
314         expectedRow[15] = new T_AccessRow(8, 0, 0);
315
316         return testSort(tc, row, expectedRow, sortid);
317     }
318
319
320     /**
321     Test a sorts with one or zero rows.
322     **/

323     boolean sortBoundaries(TransactionController tc)
324         throws StandardException
325     {
326         int failcount = 0;
327         long sortid;
328         Properties JavaDoc implParameters;
329         T_AccessRow template;
330         ColumnOrdering order[];
331         boolean alreadyInOrder;
332         long estimatedRows;
333         int estimatedRowSize;
334         T_AccessRow input[];
335         T_AccessRow expected[];
336
337         /*
338         ** The following sort parameters are the same for
339         ** every sort tested in this method.
340         */

341
342         implParameters = null;
343         template = new T_AccessRow(1, 1, 1);
344         order = new ColumnOrdering[1];
345         order[0] = new T_ColumnOrderingImpl(0, true); // ascending
346
estimatedRows = 10;
347         estimatedRowSize = 12;
348
349         /*
350         ** A no-row sort.
351         */

352
353         REPORT("(sortBoundaries) Sorting no rows");
354
355         input = new T_AccessRow[0]; // no rows in..
356
expected = new T_AccessRow[0]; // .. ==> no rows out!
357
alreadyInOrder = false;
358
359         sortid = tc.createSort(implParameters, template.getRowArray(),
360             order, new T_DummySortObserver(template), alreadyInOrder, estimatedRows,
361             estimatedRowSize);
362
363         if (!testSort(tc, input, expected, sortid))
364             failcount++;
365
366         /*
367         ** A no-row already in order sort.
368         */

369
370         REPORT("(sortBoundaries) Sorting no rows - \"already in order\"");
371
372         input = new T_AccessRow[0]; // no rows in..
373
expected = new T_AccessRow[0]; // .. ==> no rows out!
374
alreadyInOrder = true;
375
376         sortid = tc.createSort(implParameters, template.getRowArray(),
377             order, new T_DummySortObserver(template), alreadyInOrder, estimatedRows,
378             estimatedRowSize);
379
380         if (!testSort(tc, input, expected, sortid))
381             failcount++;
382
383         /*
384         ** A single-row sort.
385         */

386
387         REPORT("(sortBoundaries) Sorting a single row");
388
389         input = new T_AccessRow[1];
390         input[0] = new T_AccessRow(99, 88, 77);
391         expected = new T_AccessRow[1];
392         expected[0] = new T_AccessRow(99, 88, 77);
393         alreadyInOrder = false;
394
395         sortid = tc.createSort(implParameters, template.getRowArray(),
396             order, new T_DummySortObserver(template), alreadyInOrder, estimatedRows,
397             estimatedRowSize);
398
399         if (!testSort(tc, input, expected, sortid))
400             failcount++;
401
402         /*
403         ** A single-row already-in-order sort.
404         */

405
406         REPORT("(sortBoundaries) Sorting a single row - \"already in order\"");
407
408         input = new T_AccessRow[1];
409         input[0] = new T_AccessRow(99, 88, 77);
410         expected = new T_AccessRow[1];
411         expected[0] = new T_AccessRow(99, 88, 77);
412         alreadyInOrder = true;
413
414         sortid = tc.createSort(implParameters, template.getRowArray(),
415             order, new T_DummySortObserver(template), alreadyInOrder, estimatedRows,
416             estimatedRowSize);
417
418         if (!testSort(tc, input, expected, sortid))
419             failcount++;
420
421         /*
422         ** A single-row sort, eliminating duplicates
423         */

424
425         REPORT("(sortBoundaries) Sorting a single row - \"eliminate duplicates\"");
426
427         input = new T_AccessRow[1];
428         input[0] = new T_AccessRow(99, 88, 77);
429         expected = new T_AccessRow[1];
430         expected[0] = new T_AccessRow(99, 88, 77);
431         alreadyInOrder = false;
432
433         sortid = tc.createSort(implParameters, template.getRowArray(),
434             order, new T_DuplicateEliminator(template), alreadyInOrder, estimatedRows,
435             estimatedRowSize);
436
437         if (!testSort(tc, input, expected, sortid))
438             failcount++;
439
440         return failcount == 0;
441     }
442
443     /**
444     Test a sort where all the rows are duplicates
445     **/

446     boolean sortAllDuplicates(TransactionController tc)
447         throws StandardException
448     {
449         int failcount = 0;
450         long sortid;
451         Properties JavaDoc implParameters;
452         T_AccessRow template;
453         ColumnOrdering order[];
454         boolean alreadyInOrder;
455         long estimatedRows;
456         int estimatedRowSize;
457         T_AccessRow input[];
458         T_AccessRow expected[];
459
460         /*
461         ** The following sort parameters will be used in every
462         ** sort in this method.
463         */

464         
465         implParameters = null;
466         template = new T_AccessRow(1, 1, 1);
467
468         // Ordering first two columns, ascending
469
order = new ColumnOrdering[2];
470         order[0] = new T_ColumnOrderingImpl(0, true); // ascending
471
order[1] = new T_ColumnOrderingImpl(1, true); // ascending
472

473         alreadyInOrder = false;
474         estimatedRows = 10;
475         estimatedRowSize = 12;
476
477         input = new T_AccessRow[5];
478         input[0] = new T_AccessRow(1, 1, 1);
479         input[1] = new T_AccessRow(1, 1, 1);
480         input[2] = new T_AccessRow(1, 1, 1);
481         input[3] = new T_AccessRow(1, 1, 1);
482         input[4] = new T_AccessRow(1, 1, 1);
483
484         /*
485         ** When doing no aggregation, we expect every duplicate
486         ** to come back out.
487         */

488
489         REPORT("(sortAllDuplicates) no aggregation");
490
491         expected = new T_AccessRow[5];
492         expected[0] = new T_AccessRow(1, 1, 1);
493         expected[1] = new T_AccessRow(1, 1, 1);
494         expected[2] = new T_AccessRow(1, 1, 1);
495         expected[3] = new T_AccessRow(1, 1, 1);
496         expected[4] = new T_AccessRow(1, 1, 1);
497
498         sortid = tc.createSort(implParameters, template.getRowArray(),
499             order, new T_DummySortObserver(template), alreadyInOrder, estimatedRows,
500             estimatedRowSize);
501
502         if (!testSort(tc, input, expected, sortid))
503             failcount++;
504
505         /*
506         ** If we're doing duplicate elimination, we expect
507         ** one row back (since they're all duplicates).
508         */

509         
510         REPORT("(sortAllDuplicates) eliminate duplicates");
511
512         expected = new T_AccessRow[1];
513         expected[0] = new T_AccessRow(1, 1, 1);
514
515         sortid = tc.createSort(implParameters, template.getRowArray(),
516             order, new T_DuplicateEliminator(template), alreadyInOrder, estimatedRows,
517             estimatedRowSize);
518
519         if (!testSort(tc, input, expected, sortid))
520             failcount++;
521
522         /*
523         ** Another aggregation, this time summing up the
524         ** third column.
525         */

526
527         REPORT("(sortAllDuplicates) sum aggregate");
528
529         expected = new T_AccessRow[1];
530         expected[0] = new T_AccessRow(1, 1, 5);
531
532         sortid = tc.createSort(implParameters, template.getRowArray(),
533             order, new T_SumForIntCol(2), alreadyInOrder, estimatedRows,
534             estimatedRowSize);
535
536         if (!testSort(tc, input, expected, sortid))
537             failcount++;
538
539         return failcount == 0;
540     }
541
542     /**
543     Test a sort where we have some ascending and descending keys.
544     **/

545     boolean sortDescending(TransactionController tc)
546         throws StandardException
547     {
548         int failcount = 0;
549         long sortid;
550         Properties JavaDoc implParameters;
551         T_AccessRow template;
552         ColumnOrdering order[];
553         boolean alreadyInOrder;
554         long estimatedRows;
555         int estimatedRowSize;
556         T_AccessRow expected[];
557
558         /*
559         ** The following sort parameters will be used in every
560         ** sort in this method.
561         */

562         
563         implParameters = null;
564         template = new T_AccessRow(1, 1, 1);
565
566         alreadyInOrder = false;
567         estimatedRows = 10;
568         estimatedRowSize = 12;
569
570         /*
571         ** Straight descending sort.
572         */

573
574         REPORT("(sortDescending) no aggregation");
575
576         order = new ColumnOrdering[2];
577         order[0] = new T_ColumnOrderingImpl(0, false); // descending
578
order[1] = new T_ColumnOrderingImpl(1, false); // descending
579

580         expected = new T_AccessRow[10];
581         expected[0] = new T_AccessRow(8, 1, 1);
582         expected[1] = new T_AccessRow(4, 8, 1);
583         expected[2] = new T_AccessRow(4, 2, 1);
584         expected[3] = new T_AccessRow(4, 1, 1);
585         expected[4] = new T_AccessRow(3, 8, 1);
586         expected[5] = new T_AccessRow(3, 5, 1);
587         expected[6] = new T_AccessRow(3, 3, 1);
588         expected[7] = new T_AccessRow(3, 3, 1);
589         expected[8] = new T_AccessRow(3, 3, 1);
590         expected[9] = new T_AccessRow(1, 1, 1);
591
592         sortid = tc.createSort(implParameters, template.getRowArray(),
593             order, new T_DummySortObserver(template), alreadyInOrder, estimatedRows,
594             estimatedRowSize);
595
596         if (!testSort(tc, getSortDescendingInput(), expected, sortid))
597             failcount++;
598
599         /*
600         ** Descending sort eliminating duplicates
601         */

602
603         REPORT("(sortDescending) eliminate duplicates");
604
605         order = new ColumnOrdering[2];
606         order[0] = new T_ColumnOrderingImpl(0, false); // descending
607
order[1] = new T_ColumnOrderingImpl(1, false); // descending
608

609         expected = new T_AccessRow[8];
610         expected[0] = new T_AccessRow(8, 1, 1);
611         expected[1] = new T_AccessRow(4, 8, 1);
612         expected[2] = new T_AccessRow(4, 2, 1);
613         expected[3] = new T_AccessRow(4, 1, 1);
614         expected[4] = new T_AccessRow(3, 8, 1);
615         expected[5] = new T_AccessRow(3, 5, 1);
616         expected[6] = new T_AccessRow(3, 3, 1);
617         expected[7] = new T_AccessRow(1, 1, 1);
618
619         sortid = tc.createSort(implParameters, template.getRowArray(),
620             order, new T_DuplicateEliminator(template), alreadyInOrder, estimatedRows,
621             estimatedRowSize);
622
623         if (!testSort(tc, getSortDescendingInput(), expected, sortid))
624             failcount++;
625
626         /*
627         ** Eliminate duplicates, ascending on second column.
628         */

629
630         REPORT("(sortDescending) descending/ascending - eliminate duplicates");
631
632         order = new ColumnOrdering[2];
633         order[0] = new T_ColumnOrderingImpl(0, false); // descending
634
order[1] = new T_ColumnOrderingImpl(1, true); // ascending
635

636         expected = new T_AccessRow[8];
637         expected[0] = new T_AccessRow(8, 1, 1);
638         expected[1] = new T_AccessRow(4, 1, 1);
639         expected[2] = new T_AccessRow(4, 2, 1);
640         expected[3] = new T_AccessRow(4, 8, 1);
641         expected[4] = new T_AccessRow(3, 3, 1);
642         expected[5] = new T_AccessRow(3, 5, 1);
643         expected[6] = new T_AccessRow(3, 8, 1);
644         expected[7] = new T_AccessRow(1, 1, 1);
645
646         sortid = tc.createSort(implParameters, template.getRowArray(),
647             order, new T_DuplicateEliminator(template), alreadyInOrder, estimatedRows,
648             estimatedRowSize);
649
650         if (!testSort(tc, getSortDescendingInput(), expected, sortid))
651             failcount++;
652
653
654         return failcount == 0;
655     }
656
657     private T_AccessRow[] getSortDescendingInput()
658     {
659         T_AccessRow[] input;
660
661         input = new T_AccessRow[10];
662         input[0] = new T_AccessRow(8, 1, 1);
663         input[1] = new T_AccessRow(1, 1, 1);
664         input[2] = new T_AccessRow(3, 5, 1);
665         input[3] = new T_AccessRow(4, 1, 1);
666         input[4] = new T_AccessRow(3, 3, 1);
667         input[5] = new T_AccessRow(3, 8, 1);
668         input[6] = new T_AccessRow(3, 3, 1);
669         input[7] = new T_AccessRow(3, 3, 1);
670         input[8] = new T_AccessRow(4, 2, 1);
671         input[9] = new T_AccessRow(4, 8, 1);
672
673         return input;
674     }
675
676
677     /**
678     Insert the given rows into the given sort, and check that the
679     rows retrieved from the sort match the output rows.
680     **/

681     boolean testSort(TransactionController tc, T_AccessRow in[], T_AccessRow outrow[], long sortid)
682         throws StandardException
683     {
684         // Open a sort controller for inserting the rows.
685
SortController sort = tc.openSort(sortid);
686
687         // Insert the rows to be sorted.
688
for (int i = 0; i < in.length; i++)
689         {
690             if (verbose)
691                 REPORT("(testSort) in: " + in[i]);
692             sort.insert(in[i].getRowArray());
693         }
694
695         // Close the sort controller. This makes the rows
696
// available to be retrieved.
697
// It also means we are getting final sort statistics.
698
sort.close();
699
700         // Test the SortInfo part of sort.
701
SortInfo sort_info = sort.getSortInfo();
702         Properties JavaDoc sortprop = sort_info.getAllSortInfo(null);
703
704         String JavaDoc sortType = sortprop.getProperty(
705                 MessageService.getTextMessage(SQLState.STORE_RTS_SORT_TYPE));
706         int numRowsInput = Integer.parseInt(sortprop.getProperty(
707             MessageService.getTextMessage(SQLState.STORE_RTS_NUM_ROWS_INPUT)));
708         int numRowsOutput = Integer.parseInt(sortprop.getProperty(
709             MessageService.getTextMessage(SQLState.STORE_RTS_NUM_ROWS_OUTPUT)));
710
711         String JavaDoc external =
712               MessageService.getTextMessage(SQLState.STORE_RTS_EXTERNAL);
713         String JavaDoc internal =
714              MessageService.getTextMessage(SQLState.STORE_RTS_INTERNAL);
715         if (sortType.compareTo(internal) != 0 &&
716             sortType.compareTo(external) != 0)
717             FAIL("(testSort) unknown sortType. Expected internal or external, got " + sortType);
718
719         if (numRowsInput != in.length)
720             FAIL("(testSort) SortInfo.numRowsInput (value: " + numRowsInput +
721                 ") is not equal to in.length (value: " + in.length + ")");
722
723         if (numRowsOutput != outrow.length)
724             FAIL("(testSort) SortInfo.numRowsOutput (value: " +
725                 numRowsOutput + ") is not equal to outrow.length (value: " + outrow.length + ")");
726
727         if (sortType.equals(external))
728         {
729             int numMergeRuns = Integer.parseInt(sortprop.getProperty(
730              MessageService.getTextMessage(SQLState.STORE_RTS_NUM_MERGE_RUNS)));
731             Vector JavaDoc mergeRuns = new Vector JavaDoc();
732             StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(sortprop.getProperty(
733              MessageService.getTextMessage(SQLState.STORE_RTS_MERGE_RUNS_SIZE)),
734              "[],",false);
735             while (st.hasMoreTokens())
736                 mergeRuns.addElement(Integer.valueOf(st.nextToken().trim()));
737
738             if (mergeRuns.size() != numMergeRuns)
739                 FAIL("(testSort) the number of elements in vector SortInfo.mergeRunsSize (value: " +
740                 mergeRuns.size() + " ) is not equal to SortInfo.numMergeRuns (value: " +
741                 numMergeRuns + " )");
742
743             int totRunSize = 0;
744             for (int i = 0; i < mergeRuns.size(); i++)
745                 totRunSize += ((Integer JavaDoc) mergeRuns.elementAt(i)).intValue();
746             if (totRunSize != numRowsInput)
747                FAIL("(testSort) the sum of the elements of the vector SortInfo.mergeRunsSize (value: " +
748                 totRunSize + " ) is not equal to SortInfo.numRowsInput (value: " +
749                 numRowsInput + " )");
750         }
751
752         sort = null;
753
754         // Open a sort scan for reading the rows back.
755
ScanController scan = tc.openSortScan(sortid, false);
756
757         // Things that could go wrong.
758
boolean mismatch = false;
759         boolean toofew = false;
760         boolean toomany = false;
761
762         // Fetch the sorted rows and compare them to the rows
763
// in the outrow array.
764
T_AccessRow result = new T_AccessRow(3);
765         for (int i = 0; i < outrow.length; i++)
766         {
767             if (scan.next() == false)
768             {
769                 // We were expecting the i'th row from outrow, but
770
// it didn't show up!
771
toofew = true;
772                 FAIL("(testSort) Too few rows in sort output");
773                 break;
774             }
775
776             scan.fetch(result.getRowArray());
777             if (verbose)
778                 REPORT("(testSort) out: " + result);
779
780             if (!result.equals(outrow[i]))
781             {
782                 // The i'th row from the sort didn't match the
783
// i'th row from out.
784
mismatch = true;
785                 FAIL("(testSort) row " + result + " != " + outrow[i]);
786             }
787         }
788
789         // We should not see any more rows out of the sort,
790
// since we've exhausted the out array.
791
while (scan.next() == true)
792         {
793             scan.fetch(result.getRowArray());
794             if (verbose)
795                 REPORT("(testSort) out: " + result);
796             toomany = true;
797             FAIL("(testSort) Extra row");
798         }
799
800         // Test the ScanInfo part of sort.
801
ScanInfo scan_info = scan.getScanInfo();
802         Properties JavaDoc prop = scan_info.getAllScanInfo(null);
803
804         if (prop.getProperty(
805                 MessageService.getTextMessage(SQLState.STORE_RTS_SCAN_TYPE)
806                             ).compareTo(
807                 MessageService.getTextMessage(SQLState.STORE_RTS_SORT)) != 0)
808         {
809             FAIL("(testSort) wrong scanType. Expected sort, got " +
810                 prop.getProperty(
811                     MessageService.getTextMessage(
812                                                 SQLState.STORE_RTS_SCAN_TYPE)));
813         }
814
815         if (tc.countOpens(TransactionController.OPEN_CREATED_SORTS) != 1)
816         {
817             FAIL("(testSort) sort count before close is wrong: " +
818                  tc.countOpens(TransactionController.OPEN_CREATED_SORTS));
819         }
820
821         // Close the scan controller (which implicitly destroys the sort).
822
scan.close();
823         scan = null;
824
825         if (tc.countOpens(TransactionController.OPEN_CREATED_SORTS) != 1)
826         {
827             FAIL("(testSort) sort count after close is wrong: " +
828                  tc.countOpens(TransactionController.OPEN_CREATED_SORTS));
829         }
830
831         tc.dropSort(sortid);
832
833         if (tc.countOpens(TransactionController.OPEN_CREATED_SORTS) > 0)
834         {
835             FAIL("(testSort) a sort is still open.");
836         }
837
838         return (!mismatch && !toofew && !toomany);
839     }
840 }
841
842
843 class T_DummySortObserver implements SortObserver
844 {
845     T_AccessRow template;
846     Vector JavaDoc vector;
847
848     T_DummySortObserver(T_AccessRow template)
849     {
850         this.template = template;
851         vector = new Vector JavaDoc();
852     }
853
854     /*
855      * Methods of SortObserver
856      */

857     public DataValueDescriptor[] insertNonDuplicateKey(
858     DataValueDescriptor[] insertRow)
859     {
860         return insertRow;
861     }
862
863     public DataValueDescriptor[] insertDuplicateKey(
864     DataValueDescriptor[] insertRow,
865     DataValueDescriptor[] existingRow)
866     {
867         return insertRow;
868     }
869
870     public void addToFreeList(
871     DataValueDescriptor[] objectArray,
872     int maxFreeListSize)
873     {
874         if (vector.size() < maxFreeListSize)
875         {
876             vector.addElement(objectArray);
877         }
878     }
879
880     public DataValueDescriptor[] getArrayClone()
881         throws StandardException
882     {
883         int lastElement = vector.size();
884
885         if (lastElement > 0)
886         {
887             DataValueDescriptor[] retval =
888                 (DataValueDescriptor[]) vector.elementAt(lastElement - 1);
889             vector.removeElementAt(lastElement - 1);
890             return retval;
891         }
892         return template.getRowArrayClone();
893     }
894 }
895
896 class T_DuplicateEliminator extends T_DummySortObserver
897 {
898
899     T_DuplicateEliminator(T_AccessRow template)
900     {
901         super(template);
902     }
903     /*
904      * Methods of SortObserver
905      */

906     public DataValueDescriptor[] insertNonDuplicateKey(
907     DataValueDescriptor[] insertRow)
908     {
909         return insertRow;
910     }
911
912     public DataValueDescriptor[] insertDuplicateKey(
913     DataValueDescriptor[] insertRow,
914     DataValueDescriptor[] existingRow)
915     {
916         return null;
917     }
918 }
919
920 class T_SumForIntCol implements SortObserver
921 {
922     private int columnId;
923     
924     T_SumForIntCol(int columnId)
925     {
926         this.columnId = columnId;
927     }
928
929     /*
930      * Methods of SortObserver
931      */

932
933     public DataValueDescriptor[] insertNonDuplicateKey(
934     DataValueDescriptor[] insertRow)
935     {
936         return insertRow;
937     }
938
939     public DataValueDescriptor[] insertDuplicateKey(
940     DataValueDescriptor[] insertRow,
941     DataValueDescriptor[] existingRow)
942         throws StandardException
943     {
944
945         // We know, because this is a test program and it's only
946
// used this way, that we can safely cast the arguments
947
// to SQLInteger.
948
SQLInteger increment = (SQLInteger) insertRow[columnId];
949         SQLInteger sum = (SQLInteger) existingRow[columnId];
950
951         // Perform the aggregation.
952
sum.plus(sum, increment, sum);
953
954         return null;
955     }
956
957     public void addToFreeList(
958     DataValueDescriptor[] objectArray,
959     int maxFreeListSize)
960     {
961     }
962
963     public DataValueDescriptor[] getArrayClone()
964         throws StandardException
965     {
966         return null;
967     }
968 }
969
970
Popular Tags