1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002, 2014 Oracle and/or its affiliates.  All rights reserved.
5  *
6  */
7 
8 package com.sleepycat.je.log;
9 
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertTrue;
12 
13 import java.io.File;
14 import java.io.IOException;
15 import java.util.ArrayList;
16 import java.util.Arrays;
17 import java.util.Iterator;
18 
19 import org.junit.Test;
20 
21 import com.sleepycat.je.DatabaseException;
22 import com.sleepycat.je.DbInternal;
23 import com.sleepycat.je.Environment;
24 import com.sleepycat.je.EnvironmentConfig;
25 import com.sleepycat.je.config.EnvironmentParams;
26 import com.sleepycat.je.dbi.EnvironmentImpl;
27 import com.sleepycat.je.util.TestUtils;
28 import com.sleepycat.je.utilint.DbLsn;
29 import com.sleepycat.util.test.SharedTestUtils;
30 import com.sleepycat.util.test.TestBase;
31 import com.sleepycat.utilint.StringUtils;
32 
33 /**
34  * Check our ability to adjust the file reader buffer size.
35  */
36 public class FileReaderBufferingTest extends TestBase {
37 
38     private final File envHome;
39     private Environment env;
40     private EnvironmentImpl envImpl;
41     private ArrayList<Long> expectedLsns;
42     private ArrayList<String> expectedVals;
43 
FileReaderBufferingTest()44     public FileReaderBufferingTest() {
45         envHome = SharedTestUtils.getTestDir();
46     }
47 
48     /**
49      * Should overflow once and then grow.
50      */
51     @Test
testBasic()52     public void testBasic()
53         throws Exception {
54 
55         readLog(1050,   // starting size of object in entry
56                 0,      // object growth increment
57                 100,    // starting read buffer size
58                 "3000", // max read buffer size
59                 0);     // expected number of overflows.
60     }
61 
62     /**
63      * Should overflow once and then grow.
64      */
65     @Test
testCantGrow()66     public void testCantGrow()
67         throws Exception {
68 
69         readLog(2000,   // starting size of object in entry
70                 0,      // object growth increment
71                 100,    // starting read buffer size
72                 "1000", // max read buffer size
73                 10);    // expected number of overflows.
74     }
75 
76     /**
77      * Should overflow, grow, and then reach the max.
78      */
79     @Test
testReachMax()80     public void testReachMax()
81         throws Exception {
82 
83         readLog(1000,   // size of object in entry
84                 1000,      // object growth increment
85                 100,    // starting read buffer size
86                 "3500", // max read buffer size
87                 7);     // expected number of overflows.
88     }
89     /**
90      *
91      */
readLog(int entrySize, int entrySizeIncrement, int readBufferSize, String bufferMaxSize, int expectedOverflows)92     private void readLog(int entrySize,
93                          int entrySizeIncrement,
94                          int readBufferSize,
95                          String bufferMaxSize,
96                          int expectedOverflows)
97         throws Exception {
98 
99         try {
100 
101             EnvironmentConfig envConfig = TestUtils.initEnvConfig();
102             envConfig.setAllowCreate(true);
103             envConfig.setConfigParam
104                 (EnvironmentParams.LOG_ITERATOR_MAX_SIZE.getName(),
105                  bufferMaxSize);
106             env = new Environment(envHome, envConfig);
107 
108             envImpl = DbInternal.getEnvironmentImpl(env);
109 
110             /* Make a log file */
111             createLogFile(10, entrySize, entrySizeIncrement);
112             SearchFileReader reader =
113                 new SearchFileReader(envImpl,
114                                      readBufferSize,
115                                      true,
116                                      DbLsn.longToLsn
117                                      (expectedLsns.get(0)),
118                                      DbLsn.NULL_LSN,
119                                      LogEntryType.LOG_TRACE);
120 
121             Iterator<Long> lsnIter = expectedLsns.iterator();
122             Iterator<String> valIter = expectedVals.iterator();
123             while (reader.readNextEntry()) {
124                 Trace rec = (Trace) reader.getLastObject();
125                 assertTrue(lsnIter.hasNext());
126                 assertEquals(reader.getLastLsn(),
127                              DbLsn.longToLsn(lsnIter.next()));
128                 assertEquals(valIter.next(), rec.getMessage());
129             }
130             assertEquals(10, reader.getNumRead());
131             assertEquals(expectedOverflows, reader.getNRepeatIteratorReads());
132 
133         } catch (Exception e) {
134             e.printStackTrace();
135             throw e;
136         } finally {
137             env.close();
138         }
139     }
140 
141     /**
142      * Write a logfile of entries, put the entries that we expect to
143      * read into a list for later verification.
144      * @return end of file LSN.
145      */
createLogFile(int numItems, int size, int sizeIncrement)146     private void createLogFile(int numItems, int size, int sizeIncrement)
147         throws IOException, DatabaseException {
148 
149         LogManager logManager = envImpl.getLogManager();
150         expectedLsns = new ArrayList<Long>();
151         expectedVals = new ArrayList<String>();
152 
153         for (int i = 0; i < numItems; i++) {
154             /* Add a debug record just to be filler. */
155             int recordSize = size + (i * sizeIncrement);
156             byte[] filler = new byte[recordSize];
157             Arrays.fill(filler, (byte)i);
158             String val = StringUtils.fromUTF8(filler);
159 
160             Trace rec = new Trace(val);
161             long lsn = rec.trace(envImpl, rec);
162             expectedLsns.add(new Long(lsn));
163             expectedVals.add(val);
164         }
165 
166         logManager.flush();
167         envImpl.getFileManager().clear();
168     }
169 }
170