KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derbyTesting.unitTests.store.T_FileSystemData
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 import org.apache.derby.impl.store.raw.data.*;
25
26 import org.apache.derbyTesting.unitTests.harness.T_MultiThreadedIterations;
27 import org.apache.derbyTesting.unitTests.harness.T_Fail;
28
29 import org.apache.derby.iapi.services.context.ContextService;
30 import org.apache.derby.iapi.services.context.ContextManager;
31 import org.apache.derby.iapi.services.locks.*;
32 import org.apache.derby.iapi.services.monitor.Monitor;
33 import org.apache.derby.iapi.services.sanity.SanityManager;
34 import org.apache.derby.iapi.services.io.Storable;
35 import org.apache.derby.iapi.services.property.PropertyUtil;
36
37 import org.apache.derby.iapi.error.StandardException;
38 import org.apache.derby.iapi.store.raw.*;
39
40 import org.apache.derby.iapi.store.raw.xact.RawTransaction;
41 import org.apache.derby.iapi.store.raw.data.RawContainerHandle;
42
43 import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo;
44 import org.apache.derby.iapi.reference.Property;
45
46 import java.io.*;
47 import java.util.Properties JavaDoc;
48 /**
49     An Impl unittest for rawstore data that is based on the FileSystem
50 */

51
52 public class T_FileSystemData extends T_MultiThreadedIterations {
53
54     private static final String JavaDoc testService = "fileSystemDataTest";
55
56     static final String JavaDoc REC_001 = "McLaren";
57     static final String JavaDoc REC_002 = "Ferrari";
58     static final String JavaDoc REC_003 = "Benetton";
59     static final String JavaDoc REC_004 = "Prost";
60     static final String JavaDoc REC_005 = "Tyrell";
61     static final String JavaDoc REC_006 = "Derby, Natscape, Goatscape, the popular names";
62     static final String JavaDoc REC_007 = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
63
64     static final String JavaDoc SP1 = "savepoint1";
65     static final String JavaDoc SP2 = "savepoint2";
66
67
68     static RawStoreFactory factory;
69     static LockFactory lf;
70     static long commonContainer = -1;
71
72     static boolean testRollback; // initialize in start
73
static final String JavaDoc TEST_ROLLBACK_OFF = "derby.RawStore.RollbackTestOff";
74
75     private static ContextService contextService;
76     private T_Util t_util;
77
78     public T_FileSystemData()
79     {
80         super();
81     }
82
83     /**
84       @exception StandardException cannot startup the context service
85      */

86     public void boot(boolean create, Properties JavaDoc startParams)
87          throws StandardException
88     {
89         super.boot(create, startParams);
90         contextService = ContextService.getFactory();
91     }
92
93
94     /*
95     ** Methods required by T_Generic
96     */

97
98     protected String JavaDoc getModuleToTestProtocolName() {
99         return RawStoreFactory.MODULE;
100     }
101
102
103     /**
104         Run the tests
105
106         @exception T_Fail Unexpected behaviour from the API
107      */

108     protected void setupTest() throws T_Fail
109     {
110         String JavaDoc rollbackOff = PropertyUtil.getSystemProperty(TEST_ROLLBACK_OFF);
111         testRollback = !Boolean.valueOf(rollbackOff).booleanValue();
112
113
114         // don't automatic boot this service if it gets left around
115
if (startParams == null) {
116             startParams = new Properties JavaDoc();
117         }
118
119         // see if we are testing encryption
120
startParams = T_Util.setEncryptionParam(startParams);
121
122         startParams.put(Property.NO_AUTO_BOOT, Boolean.TRUE.toString());
123         // remove the service directory to ensure a clean run
124
startParams.put(Property.DELETE_ON_CREATE, Boolean.TRUE.toString());
125
126         try {
127             factory = (RawStoreFactory) Monitor.createPersistentService(getModuleToTestProtocolName(),
128                                 testService, startParams);
129             if (factory == null) {
130                 throw T_Fail.testFailMsg(getModuleToTestProtocolName() + " service not started.");
131             }
132
133             lf = factory.getLockFactory();
134             if (lf == null) {
135                 throw T_Fail.testFailMsg("LockFactory.MODULE not found");
136             }
137         } catch (StandardException mse) {
138             throw T_Fail.exceptionFail(mse);
139         }
140
141         t_util = new T_Util(factory, lf, contextService);
142         commonContainer = commonContainer();
143
144         return;
145     }
146
147
148     /**
149      * T_MultiThreadedIteration method
150      *
151      * @exception T_Fail Unexpected behaviour from the API
152      */

153     protected void joinSetupTest() throws T_Fail {
154
155         T_Fail.T_ASSERT(factory != null, "raw store factory not setup ");
156         T_Fail.T_ASSERT(contextService != null, "Context service not setup ");
157         T_Fail.T_ASSERT(commonContainer != -1, "common container not setup ");
158
159         t_util = new T_Util(factory, lf, contextService);
160
161     }
162
163     protected T_MultiThreadedIterations newTestObject() {
164         return new T_FileSystemData();
165     }
166
167     /**
168       run the test
169
170       @exception T_Fail Unexpected behaviour from the API
171     */

172     protected void runTestSet() throws T_Fail {
173
174         // get a utility helper
175

176         ContextManager cm1 = contextService.newContextManager();
177         contextService.setCurrentContextManager(cm1);
178
179         try {
180
181             runCostEstimationTests();
182             runAllocationTests();
183
184         } catch (StandardException se) {
185
186             cm1.cleanupOnError(se);
187             throw T_Fail.exceptionFail(se);
188         }
189         finally {
190
191             contextService.resetCurrentContextManager(cm1);
192         }
193     }
194
195     /*
196      * create a container that all threads can use
197      */

198     private long commonContainer() throws T_Fail
199     {
200         ContextManager cm1 = contextService.newContextManager();
201         contextService.setCurrentContextManager(cm1);
202         long cid;
203
204         try {
205             Transaction t = t_util.t_startTransaction();
206             cid = t_util.t_addContainer(t, 0);
207             t_util.t_commit(t);
208             t.close();
209         }
210         catch (StandardException se) {
211
212             cm1.cleanupOnError(se);
213             throw T_Fail.exceptionFail(se);
214         }
215         finally {
216             contextService.resetCurrentContextManager(cm1);
217         }
218         return cid;
219     }
220
221     protected void runCostEstimationTests() throws T_Fail, StandardException
222     {
223         CostEstimationTest1();
224     }
225
226     protected void runAllocationTests() throws T_Fail, StandardException
227     {
228         // don't run these for > 2 threads
229
if (threadNumber < 2)
230         {
231             AllocTest1(); // test remove and reuse of page
232
AllocTest2(); // test remove and drop and rollback of remove
233
AllocTest3(); // test multiple alloc page
234
AllocTest4(); // test preallocation
235
}
236
237         // can't get this test to pass consistently because it depends on
238
// timing of the cache.
239
// AllocTest5(); // test gettting 1/2 filled page for insert
240

241         AllocMTest1(commonContainer); // test multi thread access to the same container
242
}
243
244     /**
245         @exception T_Fail Unexpected behaviour from the API
246         @exception StandardException Standard Derby error policy
247     */

248     protected void CostEstimationTest1() throws StandardException, T_Fail
249     {
250         // getEstimatedRowCount(0), setEstimatedRowCount(long count, int flag),
251
// getEstimatedPageCount(int flag);
252

253         Transaction t = t_util.t_startTransaction();
254         long cid = t_util.t_addContainer(t, 0);
255         t_util.t_commit(t);
256
257         ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
258
259         try
260         {
261             int numRows = 10;
262             T_RawStoreRow row = new T_RawStoreRow(REC_001);
263             RecordHandle rh[] = new RecordHandle[numRows];
264
265             // insert numRows rows into container
266
for (int i = 0; i < numRows; i++)
267                 rh[i] = t_util.t_insert(c, row);
268
269             t_util.t_commit(t);
270
271             c = t_util.t_openContainer(t, 0, cid, true);
272             if ((c.getEstimatedRowCount(0) != numRows) &&
273                 (c.getEstimatedRowCount(0) != (numRows - 1)))
274             {
275                 // due to timing, sometimes estimate row count is 9 rather than
276
// 10.
277

278                 throw T_Fail.testFailMsg(
279                     "expect estimated row count to be " + (numRows - 1) +
280                     " or " + numRows +
281                          ", got " + c.getEstimatedRowCount(0));
282             }
283
284             // now update them that cause overflowing - expect the same row count
285
T_RawStoreRow longRow = new T_RawStoreRow(REC_007);
286             for (int i = 0; i < numRows; i++)
287                 t_util.t_update(c, rh[i], longRow);
288
289             t_util.t_commit(t);
290
291             c = t_util.t_openContainer(t, 0, cid, true);
292             if (c.getEstimatedRowCount(0) != numRows)
293
294             if ((c.getEstimatedRowCount(0) != numRows) &&
295                 (c.getEstimatedRowCount(0) != (numRows - 1)))
296             {
297                 // due to timing, sometimes estimate row count is 9 rather than
298
// 10.
299

300                 throw T_Fail.testFailMsg(
301                     "expect after update same estimated row count, but it is not." +
302                     "expect estimated row count to be " + (numRows - 1) +
303                     " or " + numRows + ", got " + c.getEstimatedRowCount(0));
304             }
305
306             // now focibly set the row count
307
c.setEstimatedRowCount(2*numRows, 0);
308
309             if (c.getEstimatedRowCount(0) != 2*numRows)
310                 throw T_Fail.testFailMsg("forcibly setting estimated row count doesn't seem to work");
311
312             // now purge some rows, this should alter the row count.
313
Page p = null;
314             long pnum = 0;
315             long purgedCount = 0;
316             for (p = c.getFirstPage(); p != null; p = c.getNextPage(pnum))
317             {
318                 int rcount = p.recordCount()/3;
319                 pnum = p.getPageNumber();
320
321                 p.deleteAtSlot(0, true, (LogicalUndo)null);
322                 p.purgeAtSlot(rcount, rcount, true); // purget the middle 1/3 of the page
323
purgedCount += rcount + 1;
324
325                 p.unlatch();
326             }
327         
328             t_util.t_commit(t);
329
330             c = t_util.t_openContainer(t, 0, cid, true);
331             if (c.getEstimatedRowCount(0) != (2*numRows - purgedCount))
332                 throw T_Fail.testFailMsg("expect " + (2*numRows-purgedCount) +
333                                          " after purge");
334         
335             // now get rid of some pages to alter the row count
336
REPORT("before page delete, estRC = " + (2*numRows) + " - " + purgedCount);
337
338             for (p = c.getFirstPage(); p != null; p = c.getNextPage(pnum))
339             {
340                 pnum = p.getPageNumber();
341                 if ((pnum%2) == 0)
342                 {
343                     purgedCount += p.nonDeletedRecordCount();
344                     c.removePage(p);
345                 }
346                 else
347                     p.unlatch();
348             }
349
350             t_util.t_commit(t);
351
352             c = t_util.t_openContainer(t, 0, cid, true);
353             if (c.getEstimatedRowCount(0) != (2*numRows - purgedCount))
354                 throw T_Fail.testFailMsg("expect " + (2*numRows-purgedCount) +
355                                          " after page remove, got " + c.getEstimatedRowCount(0));
356
357             PASS("CostEstimationTest1");
358         }
359         finally
360         {
361             t_util.t_commit(t);
362             t.close();
363         }
364
365
366     }
367
368     protected void AllocTest1() throws StandardException, T_Fail
369     {
370         /**
371           test remove and reuse of page
372         */

373         Transaction t = t_util.t_startTransaction();
374
375         try
376         {
377             long cid = t_util.t_addContainer(t, 0);
378             t_util.t_commit(t);
379
380             ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
381
382         // create 5 pages, each insert a row into it, then remove 2 of them
383

384             Page page1 = t_util.t_getPage(c, ContainerHandle.FIRST_PAGE_NUMBER);
385             long p1 = page1.getPageNumber();
386             T_RawStoreRow row1 = new T_RawStoreRow(REC_001);
387             t_util.t_insert(page1, row1);
388
389             Page page2 = t_util.t_addPage(c);
390             long p2 = page2.getPageNumber();
391             T_RawStoreRow row2 = new T_RawStoreRow(REC_002);
392             int rid2 = t_util.t_insert(page2, row2).getId();
393
394             Page page3 = t_util.t_addPage(c);
395             long p3 = page3.getPageNumber();
396             T_RawStoreRow row3 = new T_RawStoreRow(REC_003);
397             t_util.t_insert(page3, row3);
398
399             Page page4 = t_util.t_addPage(c);
400             long p4 = page4.getPageNumber();
401             T_RawStoreRow row4 = new T_RawStoreRow(REC_004);
402             int rid4 = t_util.t_insert(page4, row4).getId();
403
404             Page page5 = t_util.t_addPage(c);
405             long p5 = page5.getPageNumber();
406             T_RawStoreRow row5 = new T_RawStoreRow(REC_005);
407             t_util.t_insert(page5, row5);
408
409             t_util.t_removePage(c, page2);
410             t_util.t_removePage(c, page4);
411             t_util.t_commit(t);
412
413         // now all the pages are unlatched
414
// pages 2, 4 has been removed, pages 1, 3, 5 has not
415
// make sure pages that are removed cannot be found again
416
c = t_util.t_openContainer(t, 0, cid, true);
417
418             if (SanityManager.DEBUG)
419                 SanityManager.DEBUG("SpaceTrace", "containeropened");
420
421             Page p = c.getFirstPage();
422             if (p == null)
423                 throw T_Fail.testFailMsg("get first page failed: expect " + p1 + " got null");
424             if (p.getPageNumber() != p1)
425                 throw T_Fail.testFailMsg("get first page failed: expect " + p1
426                                          + " got " + p.getPageNumber());
427
428             t_util.t_commit(t);
429
430         // closing the transaction many times to see if we can get the
431
// deallocated page to free
432

433             c = t_util.t_openContainer(t, 0, cid, true);
434             p = c.getNextPage(p1);
435             if (p == null || p.getPageNumber() != p3)
436                 throw T_Fail.testFailMsg("get next page failed");
437             t_util.t_commit(t);
438
439             c = t_util.t_openContainer(t, 0, cid, true);
440             p = c.getNextPage(p3);
441             if (p == null || p.getPageNumber() != p5)
442                 throw T_Fail.testFailMsg("get next page failed");
443             t_util.t_commit(t);
444         
445             c = t_util.t_openContainer(t, 0, cid, true);
446             p = t_util.t_getLastPage(c); // make sure it skips over p5
447
if (p == null || p.getPageNumber() != p5)
448                 throw T_Fail.testFailMsg("getLastPage failed");
449             t_util.t_commit(t);
450
451         // see if we can get any deallocated page back in 10 attempts
452
// of add page
453
int tries = 100;
454             T_RawStoreRow row6 = new T_RawStoreRow(REC_001);
455
456             long pnums[] = new long[tries];
457             int rids[] = new int[tries];
458             pnums[0] = p2; // pages 2 and 4 have been removed for a long time
459
rids[0] = rid2;
460             pnums[1] = p4;
461             rids[1] = rid4;
462
463             int match = -1;
464             int i;
465             for (i = 2 ; match < 0 && i < tries; i++)
466             {
467                 c = t_util.t_openContainer(t, 0, cid, true);
468                 p = t_util.t_addPage(c);
469                 pnums[i] = p.getPageNumber();
470
471                 for (int j = 0; j < i-1; j++)
472                 {
473                     if (pnums[j] == pnums[i])
474                     {
475                         match = j;
476                         break;
477                     }
478                 }
479
480                 if (match >= 0)
481                 {
482                     // p is a reused one, make sure it is empty
483
t_util.t_checkEmptyPage(p);
484                     RecordHandle rh = t_util.t_insert(p, row6);
485                     if (rh.getId() == rids[match])
486                         throw T_Fail.testFailMsg("reused page recordId is not preserved");
487                     break;
488                 }
489                 else
490                     rids[i] = t_util.t_insert(p, row6).getId();
491
492                 t_util.t_removePage(c, p);
493                 t_util.t_commit(t);
494             }
495             t_util.t_dropContainer(t, 0, cid); // cleanup
496

497             if (match >= 0)
498                 PASS("AllocTest1 success in " + i + " tries");
499             else
500                 REPORT("AllocTest1 Not successful in " + i +
501                        " tries. This is a timing depenedent test so this is not necessarily an indication of failure.");
502         }
503         finally
504         {
505             t_util.t_commit(t);
506             t.close();
507         }
508
509     }
510
511     protected void AllocTest2() throws StandardException, T_Fail
512     {
513         /**
514           More Test remove and reuse of page
515         */

516
517         Transaction t = t_util.t_startTransaction();
518         int numpages = 30;
519
520         try
521         {
522             long cid = t_util.t_addContainer(t, 0);
523             ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
524
525             Page[] page = new Page[numpages];
526
527             for (int i = 0; i < numpages; i++)
528             {
529                 page[i] = t_util.t_addPage(c);
530                 t_util.t_removePage(c, page[i]);
531             }
532
533             // make sure a dropped container does not cause problem for page
534
// that's been removed
535
t_util.t_dropContainer(t, 0, cid);
536
537             t_util.t_commit(t);
538
539             if (testRollback)
540             {
541                 cid = t_util.t_addContainer(t, 0);
542                 c = t_util.t_openContainer(t, 0, cid, true);
543
544                 for (int i = 0; i < numpages; i++)
545                 {
546                     page[i] = t_util.t_addPage(c);
547                     t_util.t_removePage(c, page[i]);
548                 }
549
550                 t_util.t_abort(t);
551             }
552         }
553         finally
554         {
555             t_util.t_commit(t);
556             t.close();
557         }
558
559
560         PASS("AllocTest2");
561     }
562
563     protected void AllocTest3() throws StandardException, T_Fail
564     {
565         /* test multiple alloc pages */
566
567         if (!SanityManager.DEBUG)
568         {
569             REPORT("allocTest3 cannot be run on an insane server");
570             return;
571         }
572         else
573         {
574             SanityManager.DEBUG_SET(AllocPage.TEST_MULTIPLE_ALLOC_PAGE);
575
576             Transaction t = t_util.t_startTransaction();
577
578             try
579             {
580                 long cid = t_util.t_addContainer(t, 0);
581                 t_util.t_commit(t);
582
583                 ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
584
585                 T_RawStoreRow row = new T_RawStoreRow(REC_001);
586                 int numrows = 10; // create 10 pages with 1 row each
587

588                 String JavaDoc threadName = Thread.currentThread().getName();
589
590                 Page page;
591                 for (int i = 0; i < numrows; i++)
592                 {
593                     page = t_util.t_addPage(c);
594                     t_util.t_insert(page, row);
595                     page.unlatch();
596                 }
597
598                 int checkrows = 0;
599                 long pnum;
600                 for (page = c.getFirstPage();
601                      page != null;
602                      page = c.getNextPage(pnum))
603                 {
604                     pnum = page.getPageNumber();
605                     if (page.recordCount() > 0)
606                     {
607                         t_util.t_checkFetchFirst(page, REC_001);
608                         checkrows++;
609                     }
610                     page.unlatch();
611                 }
612                 if (checkrows != numrows)
613                     throw T_Fail.testFailMsg("number of rows differ");
614
615                 t.setSavePoint(SP1, null);
616
617                 // now remove 1/2 of the pages and check results
618
int removedPages = 0;
619                 for (page = c.getFirstPage();
620                      page != null;
621                      page = c.getNextPage(pnum))
622                 {
623                     pnum = page.getPageNumber();
624                     if ((pnum % 2) == 0)
625                     {
626                         t_util.t_removePage(c, page);
627                         removedPages++;
628                     }
629                     else
630                         page.unlatch();
631                 }
632
633                 checkrows = 0;
634                 for (page = c.getFirstPage();
635                      page != null;
636                      page = c.getNextPage(pnum))
637                 {
638                     pnum = page.getPageNumber();
639                     if (page.recordCount() > 0)
640                     {
641                         t_util.t_checkFetchFirst(page, REC_001);
642                         checkrows++;
643                     }
644                     page.unlatch();
645                 }
646                 if (checkrows != numrows - removedPages)
647                     throw T_Fail.testFailMsg("number of rows differ");
648
649                 // remove every page backwards
650
long lastpage = ContainerHandle.INVALID_PAGE_NUMBER;
651                 while((page = t_util.t_getLastPage(c)) != null) // remove the last page
652
{
653                     if (lastpage == page.getPageNumber())
654                         throw T_Fail.testFailMsg("got a removed last page");
655
656                     lastpage = page.getPageNumber();
657                     t_util.t_removePage(c, page);
658                 }
659
660                 if (c.getFirstPage() != null)
661                     throw T_Fail.testFailMsg("get last page returns null but get fisrt page retuns a page");
662
663                 t.rollbackToSavePoint(SP1, null); // roll back removes
664
c = t_util.t_openContainer(t, 0, cid, true);
665
666                 checkrows = 0;
667                 for (page = c.getFirstPage();
668                      page != null;
669                      page = c.getNextPage(pnum))
670                 {
671                     pnum = page.getPageNumber();
672                     if (page.recordCount() > 0)
673                     {
674                         t_util.t_checkFetchFirst(page, REC_001);
675                         checkrows++;
676                     }
677                     page.unlatch();
678                 }
679                 if (checkrows != numrows)
680                     throw T_Fail.testFailMsg(threadName + "number of rows differ expect " +
681                                              numrows + " got " + checkrows);
682
683
684                 t_util.t_abort(t); // abort the whole thing, no rows left
685
c = t_util.t_openContainer(t, 0, cid, true);
686
687                 int countPages = 0;
688                 for (page = c.getFirstPage();
689                      page != null;
690                      page = c.getNextPage(pnum))
691                 {
692                     countPages++;
693                     pnum = page.getPageNumber();
694                     if (page.nonDeletedRecordCount() > 0)
695                     {
696                         throw T_Fail.testFailMsg("failed to remove everything " +
697                                                  page.nonDeletedRecordCount() +
698                                                  " rows left on page " + pnum);
699                     }
700                     page.unlatch();
701                 }
702
703                 if (countPages < numrows)
704                     throw T_Fail.testFailMsg("rollback of user transaction should not remove allocated pages");
705
706                 t_util.t_dropContainer(t, 0, cid);
707
708             }
709             finally
710             {
711                 SanityManager.DEBUG_CLEAR(AllocPage.TEST_MULTIPLE_ALLOC_PAGE);
712                 t_util.t_commit(t);
713                 t.close();
714             }
715             PASS("AllocTest3");
716         }
717     }
718
719     protected void AllocTest4() throws StandardException, T_Fail
720     {
721         if (!SanityManager.DEBUG)
722         {
723             REPORT("allocTest3 cannot be run on an insane server");
724             return;
725         }
726         else
727         {
728
729             SanityManager.DEBUG_SET(AllocPage.TEST_MULTIPLE_ALLOC_PAGE);
730             Transaction t = t_util.t_startTransaction();
731
732             try
733             {
734                 ////////////////////////////////////////////////////////
735
// first test preallocation large table
736
////////////////////////////////////////////////////////
737
Properties JavaDoc tableProperties = new Properties JavaDoc();
738                 tableProperties.put(Property.PAGE_SIZE_PARAMETER, Integer.toString(1024));
739                 tableProperties.put(RawStoreFactory.CONTAINER_INITIAL_PAGES, Integer.toString(100));
740
741                 long cid1 =
742                     t.addContainer(
743                         0, ContainerHandle.DEFAULT_ASSIGN_ID,
744                         ContainerHandle.MODE_DEFAULT, tableProperties, 0);
745
746                 if (cid1 < 0)
747                     throw T_Fail.testFailMsg("addContainer");
748
749                 ContainerHandle c1 = t_util.t_openContainer(t, 0, cid1, true);
750
751                 Page p1 = c1.getFirstPage();
752                 if (p1.getPageNumber() != ContainerHandle.FIRST_PAGE_NUMBER)
753                     throw T_Fail.testFailMsg("expect first page to have FIRST_PAGE_NUMBER");
754                 p1.unlatch();
755
756                 if (c1.getNextPage(ContainerHandle.FIRST_PAGE_NUMBER) != null)
757                     throw T_Fail.testFailMsg("expect to have only 1 page allocated");
758
759                 t_util.t_commit(t);
760
761                 REPORT("AllocTest4 - create preallocated container " + cid1);
762
763                 ////////////////////////////////////////////////////////
764
// next test special addpage interface
765
////////////////////////////////////////////////////////
766
long cid2 = t_util.t_addContainer(t, 0, 1024, 0, 1, false);
767                 t_util.t_commit(t);
768
769                 ContainerHandle c2 = t_util.t_openContainer(t, 0, cid2, true);
770
771                 // add page for bulk load
772
p1 = c2.addPage(ContainerHandle.ADD_PAGE_BULK);
773                 long pnum1 = p1.getPageNumber();
774                 p1.unlatch();
775
776                 // since the interface does not guarentee that anything special will
777
// actually happen, can't really test that. Just make sure that
778
// everything else works
779
Page p2 = c2.addPage();
780                 long pnum2 = p2.getPageNumber();
781                 p2.unlatch();
782
783                 Page p3 = c2.addPage(ContainerHandle.ADD_PAGE_BULK);
784                 long pnum3 = p3.getPageNumber();
785                 p3.unlatch();
786
787                 Page p = c2.getFirstPage(); // this is the first page that came with the
788
// container when it was created
789

790                 try
791                 {
792                     long pnum0 = p.getPageNumber();
793                     p.unlatch();
794                     p = c2.getNextPage(pnum0);
795                     if (p.getPageNumber() != pnum1)
796                         throw T_Fail.testFailMsg("expected pagenum " + pnum1 + " got " + p.getPageNumber());
797                     p.unlatch();
798                     p = null;
799
800                     p = c2.getNextPage(pnum1);
801                     if (p.getPageNumber() != pnum2)
802                         throw T_Fail.testFailMsg("expected pagenum " + pnum2 + " got " + p.getPageNumber());
803                     p.unlatch();
804                     p = null;
805
806                     p = c2.getNextPage(pnum2);
807                     if (p.getPageNumber() != pnum3)
808                         throw T_Fail.testFailMsg("expected pagenum " + pnum3 + " got " + p.getPageNumber());
809                     p.unlatch();
810                     p = null;
811
812                     p = c2.getNextPage(pnum3);
813                     if (p != null)
814                         throw T_Fail.testFailMsg("expected null page after " + pnum3 +
815                                              " got " + p.getPageNumber());
816
817                     // make sure rollback is unaffected
818
if (testRollback)
819                     {
820                         t_util.t_abort(t);
821                         c2 = t_util.t_openContainer(t, 0, cid2, true);
822                         p = t_util.t_getPage(c2, pnum0);
823                         t_util.t_checkEmptyPage(p);
824                         p.unlatch();
825                         p = null;
826                 
827                         p = t_util.t_getPage(c2, pnum1);
828                         t_util.t_checkEmptyPage(p);
829                         p.unlatch();
830                         p = null;
831
832                         p = t_util.t_getPage(c2, pnum2);
833                         t_util.t_checkEmptyPage(p);
834                         p.unlatch();
835                         p = null;
836
837                         p = t_util.t_getPage(c2, pnum3);
838                         t_util.t_checkEmptyPage(p);
839                         p.unlatch();
840                         p = null;
841
842                         p = t_util.t_getLastPage(c2);
843                         if (p.getPageNumber() != pnum3)
844                             throw T_Fail.testFailMsg("expect last page to be " + pnum3
845                                                  + " got " + p.getPageNumber());
846                         p.unlatch();
847                         p = null;
848                     }
849                 }
850                 finally
851                 {
852                     if (p != null)
853                         p.unlatch();
854                     p = null;
855                 }
856                 REPORT("AllocTest4 - special addPage interface " + cid2);
857
858
859                 ////////////////////////////////////////////////////////
860
// next test preallocate interface
861
////////////////////////////////////////////////////////
862
long cid3 = t_util.t_addContainer(t, 0, 1024);
863                 ContainerHandle c3 = t_util.t_openContainer(t, 0, cid3, true);
864
865                 // now preallocate 10 pages
866
c3.preAllocate(10);
867
868                 p1 = c3.getFirstPage();
869                 if (p1.getPageNumber() != ContainerHandle.FIRST_PAGE_NUMBER)
870                     throw T_Fail.testFailMsg("expect first page to have FIRST_PAGE_NUMBER");
871                 p1.unlatch();
872
873                 if (c3.getNextPage(ContainerHandle.FIRST_PAGE_NUMBER) != null)
874                     throw T_Fail.testFailMsg("expect to have only 1 page allocated");
875
876                 REPORT("AllocTest4 - preallocate interface " + cid3);
877
878                 PASS("AllocTest4 ");
879
880             }
881             finally
882             {
883                 SanityManager.DEBUG_CLEAR(AllocPage.TEST_MULTIPLE_ALLOC_PAGE);
884                 t_util.t_commit(t);
885                 t.close();
886             }
887         }
888     }
889
890     protected void AllocTest5() throws StandardException, T_Fail
891     {
892         // first create 10 1/2 filled pages with various degree of fillness
893
Transaction t = t_util.t_startTransaction();
894
895         try
896         {
897             long cid = t_util.t_addContainer(t, 0, 1024, 0, 90, false);
898             ContainerHandle c = t_util.t_openContainer(t, 0, cid, true);
899             Page p;
900
901             // the number of rows that is expected to fit into one page
902
// secret raw store calculation for 1 column rows
903
int numRows = (1024-60)/(95+8);
904
905             T_RawStoreRow rows[] = new T_RawStoreRow[numRows];
906
907             for (int j = 0; j < numRows; j++)
908                 rows[j] = new T_RawStoreRow("row " + j);
909
910             for (int i = 0; i < numRows; i++)
911             {
912                 p = t_util.t_addPage(c);
913
914                 // validate allocation cache by getting the first page
915
t_util.t_getPage(c, 1).unlatch();
916
917                 // insert different number of rows into these pages
918
for (int j = 0; j <= i; j++)
919                 {
920                     if (t_util.t_insert(p, rows[j]) == null)
921                         throw T_Fail.testFailMsg("failed to insert " + (j+1) +
922                                                  " rows into page " + p);
923                 }
924
925                 p.unlatch();
926             }
927
928             // page 1 has 0 row
929
// page 2 has 1 row
930
// page 3 has 2 rows
931
// page 4 has 3 rows
932
// page 5 has 4 rows
933
// page 6 has 5 rows (filled)
934
// page 7 has 6 rows (filled)
935
// page 8 has 7 rows (filled)
936
// page 9 has 8 rows (filled)
937
// page 10 has 9 rows (filled)
938

939
940             // these pages should be accounted for correctly because each
941
// subsequent page has > 1/8 for all the records in the container
942

943             // now go thru and use up all the space
944
p = c.getPageForInsert(0);
945             if (p != null)
946                 throw T_Fail.testFailMsg("Expect last page to be full");
947
948             // now go thru and use up all the space - since we skipped page 1
949
// on the first loop, it won't know it is a 1/2 filled page.
950
for (int i = 2; i < 6; i++)
951             {
952                 p = c.getPageForInsert(ContainerHandle.GET_PAGE_UNFILLED);
953                 if (p == null)
954                     throw T_Fail.testFailMsg("Expect next unfilled page to be " + i);
955
956                 if (p.getPageNumber() != i)
957                     throw T_Fail.testFailMsg("Expect next unfilled page to be "
958                                              + i + ", it is " + p.getPageNumber());
959
960                 t_util.t_insert(p, rows[i]);
961                 p.unlatch();
962
963                 // we should keep getting the same page back until it is full
964
while ((p = c.getPageForInsert(0)) != null)
965                 {
966                     if (p.getPageNumber() != i)
967                         throw T_Fail.testFailMsg("Don't expect page number to change from " +
968                                                  i + " to " + p.getPageNumber());
969                     t_util.t_insert(p, rows[i]);
970                     p.unlatch();
971                 }
972
973             }
974         
975             p = c.getPageForInsert(ContainerHandle.GET_PAGE_UNFILLED);
976             if (p != null)
977                 throw T_Fail.testFailMsg("don't expect any more pages to be found");
978
979         }
980         finally
981         {
982             t_util.t_commit(t);
983             t.close();
984         }
985         PASS("AllocTest5 ");
986
987     }
988
989     /*
990      * MT tests on the same container
991      */

992     protected void AllocMTest1(long cid) throws StandardException, T_Fail
993     {
994         if (SanityManager.DEBUG)
995         {
996             SanityManager.DEBUG_SET(AllocPage.TEST_MULTIPLE_ALLOC_PAGE);
997
998             // each thread will add N pages and remove N pages and still finds
999
// its own pages. Do that serveral times.
1000
int N = 20;
1001
1002            RecordHandle rh[] = new RecordHandle[N];
1003
1004            Transaction t = t_util.t_startTransaction();
1005
1006            try
1007            {
1008                T_RawStoreRow row = new T_RawStoreRow(REC_002);
1009                ContainerHandle c;
1010                Page p;
1011
1012                for (int iteration = 0; iteration < 5; iteration++)
1013                {
1014                    for (int i = 0; i < N; i++)
1015                    {
1016                        c = t_util.t_openContainer(t, 0, cid, true);
1017
1018                        p = t_util.t_addPage(c);
1019                        rh[i] = t_util.t_insert(p, row);
1020                        p.unlatch();
1021
1022                        t_util.t_commit(t);
1023                    }
1024
1025                    for (int i = 0; i < N; i++)
1026                    {
1027                        c = t_util.t_openContainer(t, 0, cid, true);
1028                        t_util.t_checkFetch(c, rh[i], REC_002);
1029
1030                        t.setSavePoint(SP1, null);
1031
1032                        p = t_util.t_getPage(c, rh[i].getPageNumber());
1033                        t_util.t_removePage(c, p);
1034
1035                        if ((iteration%3) == 1)
1036                        {
1037                            t.rollbackToSavePoint(SP1, null);
1038                        }
1039
1040                        // sometimes commit sometimes abort
1041
if (iteration % 2 == 0)
1042                            t_util.t_abort(t);
1043                        else
1044                            t_util.t_commit(t);
1045                    }
1046
1047                    // if I aborted, remove them now
1048
if ((iteration % 2) == 0 ||
1049                        (iteration % 3) == 1)
1050                    {
1051                        for (int i = 0; i < N; i++)
1052                        {
1053                            c = t_util.t_openContainer(t, 0, cid, true);
1054                            t_util.t_checkFetch(c, rh[i], REC_002);
1055
1056                            p = t_util.t_getPage(c, rh[i].getPageNumber());
1057                            t_util.t_removePage(c, p);
1058                            t_util.t_commit(t);
1059                        }
1060                    }
1061
1062                    // at any given time, there should be <= (N*numthread)+1 pages
1063
int max = (N*getNumThreads())+1;
1064
1065                    c = t_util.t_openContainer(t, 0, cid, false);
1066                    long pnum = 0;
1067                    int countPages = 0;
1068
1069                    for (p = c.getFirstPage();
1070                         p != null;
1071                         p = c.getNextPage(pnum))
1072                    {
1073                        countPages++;
1074                        pnum = p.getPageNumber();
1075                        p.unlatch();
1076                        t_util.t_commit(t); // release container lock
1077

1078                        c = t_util.t_openContainer(t, 0, cid, false);
1079                    }
1080
1081                    t_util.t_commit(t); // release container lock
1082

1083                    if (countPages > max)
1084                        throw T_Fail.testFailMsg("some pages may not be reused, expect " +
1085                                                 max + " got " + countPages);
1086                    else
1087                        REPORT("AllocMTest1 got " + countPages );
1088                }
1089                
1090            }
1091            finally
1092            {
1093                SanityManager.DEBUG_CLEAR(AllocPage.TEST_MULTIPLE_ALLOC_PAGE);
1094                t_util.t_commit(t);
1095                t.close();
1096            }
1097
1098            PASS("AllocMTest1");
1099        }
1100        else
1101        {
1102            REPORT("AllocMTest1 cannot be run on an insane server");
1103            return;
1104        }
1105    }
1106}
1107
Popular Tags