embulk-output-oracle 0.6.3 → 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
}
|