embulk-output-oracle 0.6.3 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +43 -0
- data/build.gradle +2 -2
- data/classpath/{embulk-output-jdbc-0.6.3.jar → embulk-output-jdbc-0.6.4.jar} +0 -0
- data/classpath/embulk-output-oracle-0.6.4.jar +0 -0
- data/lib/embulk/native/x86_64-linux/libembulk-output-oracle-oci.so +0 -0
- data/lib/embulk/native/x86_64-windows/embulk-output-oracle-oci.dll +0 -0
- data/src/main/cpp/common/embulk-output-oracle-oci.cpp +27 -0
- data/src/main/cpp/linux/build.sh +15 -0
- data/src/main/cpp/windows/build.bat +26 -0
- data/src/main/cpp/windows/dllmain.cpp +25 -0
- data/src/main/cpp/windows/embulk-output-oracle-oci.sln +20 -0
- data/src/main/cpp/windows/embulk-output-oracle-oci.vcxproj +171 -0
- data/src/main/java/org/embulk/output/oracle/DirectBatchInsert.java +5 -39
- data/src/main/java/org/embulk/output/oracle/oci/BulkOCI.java +15 -0
- data/src/main/java/org/embulk/output/oracle/oci/OCI.java +1 -0
- data/src/main/java/org/embulk/output/oracle/oci/OCIManager.java +3 -2
- data/src/main/java/org/embulk/output/oracle/oci/OCIWrapper.java +103 -37
- data/src/main/java/org/embulk/output/oracle/oci/PrimitiveBulkOCI.java +47 -0
- data/src/main/java/org/embulk/output/oracle/oci/RowBuffer.java +50 -46
- data/src/main/java/org/embulk/output/oracle/oci/TableDefinition.java +9 -0
- data/src/test/java/org/embulk/output/oracle/OracleOutputPluginTest.java +622 -133
- data/src/test/resources/oracle/data/test3/test3.csv +9999 -0
- data/src/test/resources/oracle/yml/test-insert-direct-oci-method-large.yml +29 -0
- metadata +19 -8
- data/classpath/embulk-output-oracle-0.6.3.jar +0 -0
- data/src/test/java/org/embulk/output/oracle/OracleOutputPluginTestImpl.java +0 -620
@@ -0,0 +1,15 @@
|
|
1
|
+
package org.embulk.output.oracle.oci;
|
2
|
+
|
3
|
+
import jnr.ffi.Pointer;
|
4
|
+
import jnr.ffi.types.u_int16_t;
|
5
|
+
import jnr.ffi.types.u_int32_t;
|
6
|
+
|
7
|
+
public interface BulkOCI {
|
8
|
+
|
9
|
+
short embulk_output_oracle_OCIDirPathColArrayEntriesSet(Pointer dpca,
|
10
|
+
Pointer errhp,
|
11
|
+
@u_int16_t short columnCount,
|
12
|
+
@u_int32_t int rowCount,
|
13
|
+
Pointer data,
|
14
|
+
Pointer sizes);
|
15
|
+
}
|
@@ -32,6 +32,7 @@ public interface OCI
|
|
32
32
|
static int OCI_ATTR_SCHEMA_NAME = 9;
|
33
33
|
static int OCI_ATTR_CHARSET_ID = 31;
|
34
34
|
static int OCI_ATTR_DATEFORMAT = 75;
|
35
|
+
static int OCI_ATTR_BUF_SIZE = 77;
|
35
36
|
static int OCI_ATTR_NUM_ROWS = 81;
|
36
37
|
static int OCI_ATTR_NUM_COLS = 102;
|
37
38
|
static int OCI_ATTR_LIST_COLUMNS = 103;
|
@@ -20,7 +20,8 @@ public class OCIManager
|
|
20
20
|
private Map<Object, OCIWrapperAndCounter> ociAndCounters = new HashMap<Object, OCIWrapperAndCounter>();
|
21
21
|
|
22
22
|
|
23
|
-
public OCIWrapper open(Object key, String dbName, String userName, String password, TableDefinition tableDefinition
|
23
|
+
public OCIWrapper open(Object key, String dbName, String userName, String password, TableDefinition tableDefinition, int bufferSize)
|
24
|
+
throws SQLException
|
24
25
|
{
|
25
26
|
synchronized(ociAndCounters) {
|
26
27
|
OCIWrapperAndCounter ociAndCounter;
|
@@ -31,7 +32,7 @@ public class OCIManager
|
|
31
32
|
ociAndCounter = new OCIWrapperAndCounter();
|
32
33
|
ociAndCounter.oci = new OCIWrapper();
|
33
34
|
ociAndCounter.oci.open(dbName, userName, password);
|
34
|
-
ociAndCounter.oci.prepareLoad(tableDefinition);
|
35
|
+
ociAndCounter.oci.prepareLoad(tableDefinition, bufferSize);
|
35
36
|
ociAndCounters.put(key, ociAndCounter);
|
36
37
|
}
|
37
38
|
ociAndCounter.counter++;
|
@@ -1,13 +1,17 @@
|
|
1
1
|
package org.embulk.output.oracle.oci;
|
2
2
|
|
3
|
+
import java.io.File;
|
4
|
+
import java.net.MalformedURLException;
|
5
|
+
import java.net.URISyntaxException;
|
6
|
+
import java.net.URL;
|
3
7
|
import java.nio.ByteBuffer;
|
4
8
|
import java.nio.charset.Charset;
|
5
9
|
import java.sql.SQLException;
|
6
10
|
|
7
11
|
import jnr.ffi.LibraryLoader;
|
12
|
+
import jnr.ffi.Platform;
|
8
13
|
import jnr.ffi.Pointer;
|
9
14
|
import jnr.ffi.Runtime;
|
10
|
-
import jnr.ffi.provider.BoundedMemoryIO;
|
11
15
|
import jnr.ffi.provider.jffi.ArrayMemoryIO;
|
12
16
|
import jnr.ffi.provider.jffi.ByteBufferMemoryIO;
|
13
17
|
|
@@ -17,7 +21,10 @@ import org.slf4j.Logger;
|
|
17
21
|
|
18
22
|
public class OCIWrapper
|
19
23
|
{
|
24
|
+
private static final String PLUGIN_NAME = "embulk-output-oracle";
|
25
|
+
|
20
26
|
private static OCI oci;
|
27
|
+
private static BulkOCI bulkOci;
|
21
28
|
|
22
29
|
private final Logger logger = Exec.getLogger(getClass());
|
23
30
|
|
@@ -31,6 +38,8 @@ public class OCIWrapper
|
|
31
38
|
|
32
39
|
private TableDefinition tableDefinition;
|
33
40
|
private int maxRowCount;
|
41
|
+
private long totalRows;
|
42
|
+
private int loadCount;
|
34
43
|
|
35
44
|
private boolean errorOccured;
|
36
45
|
private boolean committedOrRollbacked;
|
@@ -43,14 +52,17 @@ public class OCIWrapper
|
|
43
52
|
|
44
53
|
synchronized (OCIWrapper.class) {
|
45
54
|
if (oci == null) {
|
46
|
-
oci =
|
55
|
+
oci = loadOCILibrary();
|
56
|
+
}
|
57
|
+
if (bulkOci == null) {
|
58
|
+
bulkOci = loadBulkOCILibrary(oci);
|
47
59
|
}
|
48
60
|
}
|
49
61
|
}
|
50
62
|
|
51
|
-
private OCI
|
63
|
+
private OCI loadOCILibrary()
|
52
64
|
{
|
53
|
-
logger.info("Loading OCI library.");
|
65
|
+
logger.info("OCI : Loading OCI library.");
|
54
66
|
|
55
67
|
// "oci" for Windows, "clntsh" for Linux
|
56
68
|
StringBuilder libraryNames = new StringBuilder();
|
@@ -69,12 +81,57 @@ public class OCIWrapper
|
|
69
81
|
throw new UnsatisfiedLinkError("Cannot find library: " + libraryNames);
|
70
82
|
}
|
71
83
|
|
84
|
+
private BulkOCI loadBulkOCILibrary(OCI oci)
|
85
|
+
{
|
86
|
+
String libraryName = "embulk-output-oracle-oci";
|
87
|
+
logger.info("OCI : Loading " + libraryName + " library.");
|
88
|
+
|
89
|
+
Platform platform = Platform.getNativePlatform();
|
90
|
+
|
91
|
+
File folder = getPluginRoot();
|
92
|
+
folder = new File(new File(new File(new File(folder ,"lib"), "embulk"), "native"), platform.getName());
|
93
|
+
|
94
|
+
File file = new File(folder, System.mapLibraryName(libraryName));
|
95
|
+
if (!file.exists()) {
|
96
|
+
logger.info("OCI : Library '" + file.getAbsolutePath() + "' doesn't exist, so Java implementation is used instead.");
|
97
|
+
return new PrimitiveBulkOCI(oci);
|
98
|
+
}
|
99
|
+
|
100
|
+
logger.info("OCI : Library '" + file.getAbsolutePath() + "' is found.");
|
101
|
+
return LibraryLoader.create(BulkOCI.class).search(folder.getAbsolutePath()).failImmediately().load(libraryName);
|
102
|
+
}
|
103
|
+
|
104
|
+
private File getPluginRoot()
|
105
|
+
{
|
106
|
+
try {
|
107
|
+
URL url = getClass().getResource("/" + getClass().getName().replace('.', '/') + ".class");
|
108
|
+
if (url.toString().startsWith("jar:")) {
|
109
|
+
url = new URL(url.toString().replaceAll("^jar:", "").replaceAll("![^!]*$", ""));
|
110
|
+
}
|
111
|
+
|
112
|
+
File folder = new File(url.toURI()).getParentFile();
|
113
|
+
for (;; folder = folder.getParentFile()) {
|
114
|
+
if (folder == null) {
|
115
|
+
String message = String.format("OCI : %s folder not found.", PLUGIN_NAME);
|
116
|
+
throw new RuntimeException(message);
|
117
|
+
}
|
118
|
+
|
119
|
+
if (folder.getName().startsWith(PLUGIN_NAME)) {
|
120
|
+
return folder;
|
121
|
+
}
|
122
|
+
}
|
123
|
+
} catch (MalformedURLException | URISyntaxException e) {
|
124
|
+
throw new RuntimeException(e);
|
125
|
+
}
|
126
|
+
}
|
127
|
+
|
72
128
|
public void open(String dbName, String userName, String password) throws SQLException
|
73
129
|
{
|
74
130
|
Pointer envHandlePointer = createPointerPointer();
|
131
|
+
// OCI_THREADED is not needed because synchronized in Java side.
|
75
132
|
check("OCIEnvCreate", oci.OCIEnvCreate(
|
76
133
|
envHandlePointer,
|
77
|
-
OCI.OCI_THREADED
|
134
|
+
/*OCI.OCI_THREADED |*/ OCI.OCI_OBJECT,
|
78
135
|
null,
|
79
136
|
null,
|
80
137
|
null,
|
@@ -126,10 +183,27 @@ public class OCIWrapper
|
|
126
183
|
dpHandle = dpHandlePointer.getPointer(0);
|
127
184
|
}
|
128
185
|
|
129
|
-
public void prepareLoad(TableDefinition tableDefinition) throws SQLException
|
186
|
+
public void prepareLoad(TableDefinition tableDefinition, int bufferSize) throws SQLException
|
130
187
|
{
|
131
188
|
this.tableDefinition = tableDefinition;
|
132
189
|
|
190
|
+
check("OCIAttrSet(OCI_ATTR_BUF_SIZE)", oci.OCIAttrSet(
|
191
|
+
dpHandle,
|
192
|
+
OCI.OCI_HTYPE_DIRPATH_CTX,
|
193
|
+
createPointer(bufferSize),
|
194
|
+
4,
|
195
|
+
OCI.OCI_ATTR_BUF_SIZE,
|
196
|
+
errHandle));
|
197
|
+
|
198
|
+
int numRows = Math.max(bufferSize / tableDefinition.getRowSize(), 16);
|
199
|
+
check("OCIAttrSet(OCI_ATTR_NUM_ROWS)", oci.OCIAttrSet(
|
200
|
+
dpHandle,
|
201
|
+
OCI.OCI_HTYPE_DIRPATH_CTX,
|
202
|
+
createPointer(numRows),
|
203
|
+
4,
|
204
|
+
OCI.OCI_ATTR_NUM_ROWS,
|
205
|
+
errHandle));
|
206
|
+
|
133
207
|
if (tableDefinition.getSchemaName() != null) {
|
134
208
|
Pointer schemaName = createPointer(tableDefinition.getSchemaName());
|
135
209
|
check("OCIAttrSet(OCI_ATTR_NAME)", oci.OCIAttrSet(
|
@@ -269,7 +343,6 @@ public class OCIWrapper
|
|
269
343
|
dpstrHandle = dpstrHandlePointer.getPointer(0);
|
270
344
|
|
271
345
|
Pointer maxRowCountPointer = createPointer(0);
|
272
|
-
|
273
346
|
check("OCIAttrGet(OCI_ATTR_NUM_ROWS)", oci.OCIAttrGet(
|
274
347
|
dpcaHandle,
|
275
348
|
OCI.OCI_HTYPE_DIRPATH_COLUMN_ARRAY,
|
@@ -278,42 +351,31 @@ public class OCIWrapper
|
|
278
351
|
OCI.OCI_ATTR_NUM_ROWS,
|
279
352
|
errHandle));
|
280
353
|
maxRowCount = maxRowCountPointer.getInt(0);
|
354
|
+
logger.info(String.format("OCI : DirectPathColumnArray.numRows = %,d", maxRowCount));
|
281
355
|
}
|
282
356
|
|
283
|
-
public
|
284
|
-
|
285
|
-
|
286
|
-
short[] sizes = rowBuffer.getSizes();
|
357
|
+
public int getMaxRowCount() {
|
358
|
+
return maxRowCount;
|
359
|
+
}
|
287
360
|
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
for (short col = 0; col < tableDefinition.getColumnCount(); col++) {
|
293
|
-
short size = sizes[i++];
|
361
|
+
public void loadBuffer(ByteBuffer buffer, ByteBuffer sizes, int rowCount) throws SQLException
|
362
|
+
{
|
363
|
+
logger.info(String.format("Loading %,d rows", rowCount));
|
364
|
+
long startTime = System.currentTimeMillis();
|
294
365
|
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
OCI.OCI_DIRPATH_COL_COMPLETE));
|
303
|
-
|
304
|
-
position += size;
|
305
|
-
}
|
366
|
+
check("OCIDirPathColArrayEntriesSet", bulkOci.embulk_output_oracle_OCIDirPathColArrayEntriesSet(
|
367
|
+
dpcaHandle,
|
368
|
+
errHandle,
|
369
|
+
(short)tableDefinition.getColumnCount(),
|
370
|
+
rowCount,
|
371
|
+
new ByteBufferMemoryIO(Runtime.getSystemRuntime(), buffer),
|
372
|
+
new ByteBufferMemoryIO(Runtime.getSystemRuntime(), sizes)));
|
306
373
|
|
307
|
-
|
308
|
-
if (rowCount == maxRowCount) {
|
309
|
-
loadRows(rowCount);
|
310
|
-
rowCount = 0;
|
311
|
-
}
|
312
|
-
}
|
374
|
+
loadRows(rowCount);
|
313
375
|
|
314
|
-
|
315
|
-
|
316
|
-
|
376
|
+
totalRows += rowCount;
|
377
|
+
double seconds = (System.currentTimeMillis() - startTime) / 1000.0;
|
378
|
+
logger.info(String.format("> %.2f seconds (loaded %,d rows in total)", seconds, totalRows));
|
317
379
|
}
|
318
380
|
|
319
381
|
private void loadRows(int rowCount) throws SQLException
|
@@ -334,6 +396,7 @@ public class OCIWrapper
|
|
334
396
|
check("OCIDirPathColArrayToStream", result);
|
335
397
|
}
|
336
398
|
|
399
|
+
loadCount++;
|
337
400
|
check("OCIDirPathLoadStream", oci.OCIDirPathLoadStream(
|
338
401
|
dpHandle,
|
339
402
|
dpstrHandle,
|
@@ -358,6 +421,9 @@ public class OCIWrapper
|
|
358
421
|
public void commit() throws SQLException
|
359
422
|
{
|
360
423
|
committedOrRollbacked = true;
|
424
|
+
if (loadCount > 0) {
|
425
|
+
logger.info(String.format("OCI : OCIDirPathLoadStream : %,d rows x %,d times.", totalRows / loadCount, loadCount));
|
426
|
+
}
|
361
427
|
logger.info("OCI : start to commit.");
|
362
428
|
|
363
429
|
try {
|
@@ -0,0 +1,47 @@
|
|
1
|
+
package org.embulk.output.oracle.oci;
|
2
|
+
|
3
|
+
import jnr.ffi.Pointer;
|
4
|
+
import jnr.ffi.types.u_int16_t;
|
5
|
+
import jnr.ffi.types.u_int32_t;
|
6
|
+
|
7
|
+
public class PrimitiveBulkOCI implements BulkOCI {
|
8
|
+
|
9
|
+
private final OCI oci;
|
10
|
+
|
11
|
+
|
12
|
+
public PrimitiveBulkOCI(OCI oci)
|
13
|
+
{
|
14
|
+
this.oci = oci;
|
15
|
+
}
|
16
|
+
|
17
|
+
public short embulk_output_oracle_OCIDirPathColArrayEntriesSet(
|
18
|
+
Pointer dpca,
|
19
|
+
Pointer errhp,
|
20
|
+
@u_int16_t short columnCount,
|
21
|
+
@u_int32_t int rowCount,
|
22
|
+
Pointer data,
|
23
|
+
Pointer sizes) {
|
24
|
+
|
25
|
+
int index = 0;
|
26
|
+
long offset = 0;
|
27
|
+
for (int row = 0; row < rowCount; row++) {
|
28
|
+
for (short column = 0; column < columnCount; column++) {
|
29
|
+
short size = sizes.getShort(index++ * 2);
|
30
|
+
short result = oci.OCIDirPathColArrayEntrySet(
|
31
|
+
dpca,
|
32
|
+
errhp,
|
33
|
+
row,
|
34
|
+
column,
|
35
|
+
data.slice(offset),
|
36
|
+
size,
|
37
|
+
OCI.OCI_DIRPATH_COL_COMPLETE);
|
38
|
+
if (result != OCI.OCI_SUCCESS) {
|
39
|
+
return result;
|
40
|
+
}
|
41
|
+
offset += size;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
return OCI.OCI_SUCCESS;
|
46
|
+
}
|
47
|
+
}
|
@@ -2,6 +2,7 @@ package org.embulk.output.oracle.oci;
|
|
2
2
|
|
3
3
|
import java.math.BigDecimal;
|
4
4
|
import java.nio.ByteBuffer;
|
5
|
+
import java.nio.ByteOrder;
|
5
6
|
import java.nio.charset.Charset;
|
6
7
|
import java.sql.SQLException;
|
7
8
|
|
@@ -12,48 +13,46 @@ import org.embulk.output.oracle.oci.TableDefinition;
|
|
12
13
|
|
13
14
|
public class RowBuffer
|
14
15
|
{
|
16
|
+
// this value was calculated by tests
|
17
|
+
private static final double OPTIMAL_LOAD_TIME = 10;
|
18
|
+
private static final int MIN_ROW_COUNT_TO_LOAD = 100;
|
19
|
+
|
20
|
+
private final OCIWrapper oci;
|
15
21
|
private final TableDefinition table;
|
16
|
-
private final int
|
22
|
+
private final int maxRowCount;
|
17
23
|
|
18
|
-
private int
|
24
|
+
private int rowCount = 0;
|
19
25
|
private int currentColumn = 0;
|
20
26
|
|
21
|
-
private
|
27
|
+
private int rowCountToLoad;
|
28
|
+
private int totalLoadedRowCount = 0;
|
29
|
+
private int loadCount = 0;
|
30
|
+
private double totalLoadTime = 0;
|
31
|
+
|
32
|
+
private final ByteBuffer sizes;
|
33
|
+
private final ByteBuffer defaultSizes;
|
22
34
|
private final ByteBuffer buffer;
|
23
35
|
private final ByteBuffer defaultBuffer;
|
24
36
|
|
25
|
-
public RowBuffer(
|
37
|
+
public RowBuffer(OCIWrapper oci, TableDefinition table)
|
26
38
|
{
|
39
|
+
this.oci = oci;
|
27
40
|
this.table = table;
|
28
|
-
|
29
|
-
|
30
|
-
int rowSize = 0;
|
31
|
-
for (int i = 0; i < table.getColumnCount(); i++) {
|
32
|
-
rowSize += table.getColumn(i).getDataSize();
|
33
|
-
}
|
41
|
+
maxRowCount = oci.getMaxRowCount();
|
42
|
+
rowCountToLoad = maxRowCount;
|
34
43
|
|
44
|
+
ByteOrder byteOrder = Runtime.getSystemRuntime().byteOrder();
|
35
45
|
// should be direct because used by native library
|
36
|
-
buffer = ByteBuffer.allocateDirect(
|
46
|
+
buffer = ByteBuffer.allocateDirect(table.getRowSize() * maxRowCount).order(byteOrder);
|
37
47
|
// position is not updated
|
38
|
-
defaultBuffer = buffer.duplicate();
|
39
|
-
|
40
|
-
sizes = new short[table.getColumnCount() * rowCount];
|
41
|
-
}
|
42
|
-
|
43
|
-
public ByteBuffer getBuffer() {
|
44
|
-
return defaultBuffer;
|
45
|
-
}
|
48
|
+
defaultBuffer = buffer.duplicate().order(byteOrder);
|
46
49
|
|
47
|
-
|
48
|
-
|
50
|
+
sizes = ByteBuffer.allocateDirect(table.getColumnCount() * maxRowCount * 2).order(byteOrder);
|
51
|
+
defaultSizes = sizes.duplicate().order(byteOrder);
|
49
52
|
}
|
50
53
|
|
51
|
-
public void addValue(int value)
|
54
|
+
public void addValue(int value) throws SQLException
|
52
55
|
{
|
53
|
-
if (isFull()) {
|
54
|
-
throw new IllegalStateException();
|
55
|
-
}
|
56
|
-
|
57
56
|
buffer.putInt(value);
|
58
57
|
|
59
58
|
next((short)4);
|
@@ -61,10 +60,6 @@ public class RowBuffer
|
|
61
60
|
|
62
61
|
public void addValue(String value) throws SQLException
|
63
62
|
{
|
64
|
-
if (isFull()) {
|
65
|
-
throw new IllegalStateException();
|
66
|
-
}
|
67
|
-
|
68
63
|
ColumnDefinition column = table.getColumn(currentColumn);
|
69
64
|
Charset charset = column.getCharset().getJavaCharset();
|
70
65
|
|
@@ -88,14 +83,18 @@ public class RowBuffer
|
|
88
83
|
addValue(value.toPlainString());
|
89
84
|
}
|
90
85
|
|
91
|
-
private void next(short size)
|
86
|
+
private void next(short size) throws SQLException
|
92
87
|
{
|
93
|
-
sizes
|
88
|
+
sizes.putShort(size);
|
94
89
|
|
95
90
|
currentColumn++;
|
96
91
|
if (currentColumn == table.getColumnCount()) {
|
97
92
|
currentColumn = 0;
|
98
|
-
|
93
|
+
rowCount++;
|
94
|
+
|
95
|
+
if (rowCount >= rowCountToLoad) {
|
96
|
+
flush();
|
97
|
+
}
|
99
98
|
}
|
100
99
|
}
|
101
100
|
|
@@ -104,21 +103,26 @@ public class RowBuffer
|
|
104
103
|
return currentColumn;
|
105
104
|
}
|
106
105
|
|
107
|
-
public
|
108
|
-
{
|
109
|
-
return currentRow;
|
110
|
-
}
|
111
|
-
|
112
|
-
public boolean isFull()
|
106
|
+
public void flush() throws SQLException
|
113
107
|
{
|
114
|
-
|
115
|
-
|
108
|
+
if (rowCount > 0) {
|
109
|
+
synchronized (oci) {
|
110
|
+
long time = System.currentTimeMillis();
|
111
|
+
oci.loadBuffer(defaultBuffer, defaultSizes, rowCount);
|
112
|
+
totalLoadTime += System.currentTimeMillis() - time;
|
113
|
+
totalLoadedRowCount += rowCount;
|
114
|
+
loadCount += 1;
|
115
|
+
}
|
116
|
+
|
117
|
+
rowCount = 0;
|
118
|
+
currentColumn = 0;
|
119
|
+
buffer.clear();
|
120
|
+
sizes.clear();
|
116
121
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
buffer.clear();
|
122
|
+
if (loadCount >= 4) {
|
123
|
+
rowCountToLoad = Math.min(Math.max((int)(totalLoadedRowCount / totalLoadTime * OPTIMAL_LOAD_TIME), MIN_ROW_COUNT_TO_LOAD), maxRowCount);
|
124
|
+
}
|
125
|
+
}
|
122
126
|
}
|
123
127
|
|
124
128
|
}
|