Unverified 提交 a47cf2a2 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov 提交者: GitHub

Merge pull request #1283 from katzyn/external

Clean up interaction between LocalResult and ResultExternal
...@@ -186,9 +186,4 @@ public abstract class MVTempResult implements ResultExternal { ...@@ -186,9 +186,4 @@ public abstract class MVTempResult implements ResultExternal {
tempFileDeleter.deleteFile(fileRef, closeable); tempFileDeleter.deleteFile(fileRef, closeable);
} }
@Override
public void done() {
// Do nothing
}
} }
...@@ -42,7 +42,6 @@ public class LocalResult implements ResultInterface, ResultTarget { ...@@ -42,7 +42,6 @@ public class LocalResult implements ResultInterface, ResultTarget {
private int offset; private int offset;
private int limit = -1; private int limit = -1;
private ResultExternal external; private ResultExternal external;
private int diskOffset;
private boolean distinct; private boolean distinct;
private boolean randomAccess; private boolean randomAccess;
private boolean closed; private boolean closed;
...@@ -157,7 +156,6 @@ public class LocalResult implements ResultInterface, ResultTarget { ...@@ -157,7 +156,6 @@ public class LocalResult implements ResultInterface, ResultTarget {
copy.offset = 0; copy.offset = 0;
copy.limit = -1; copy.limit = -1;
copy.external = e2; copy.external = e2;
copy.diskOffset = this.diskOffset;
return copy; return copy;
} }
...@@ -231,11 +229,6 @@ public class LocalResult implements ResultInterface, ResultTarget { ...@@ -231,11 +229,6 @@ public class LocalResult implements ResultInterface, ResultTarget {
currentRow = null; currentRow = null;
if (external != null) { if (external != null) {
external.reset(); external.reset();
if (diskOffset > 0) {
for (int i = 0; i < diskOffset; i++) {
external.next();
}
}
} }
} }
...@@ -318,19 +311,19 @@ public class LocalResult implements ResultInterface, ResultTarget { ...@@ -318,19 +311,19 @@ public class LocalResult implements ResultInterface, ResultTarget {
} else { } else {
rowCount = external.addRow(values); rowCount = external.addRow(values);
} }
return; } else {
} rows.add(values);
rows.add(values); rowCount++;
rowCount++; if (rows.size() > maxMemoryRows) {
if (rows.size() > maxMemoryRows) { addRowsToDisk();
if (external == null) {
createExternalResult();
} }
addRowsToDisk();
} }
} }
private void addRowsToDisk() { private void addRowsToDisk() {
if (external == null) {
createExternalResult();
}
rowCount = external.addRows(rows); rowCount = external.addRows(rows);
rows.clear(); rows.clear();
} }
...@@ -344,41 +337,12 @@ public class LocalResult implements ResultInterface, ResultTarget { ...@@ -344,41 +337,12 @@ public class LocalResult implements ResultInterface, ResultTarget {
* This method is called after all rows have been added. * This method is called after all rows have been added.
*/ */
public void done() { public void done() {
if (distinct) {
if (distinctRows != null) {
rows = distinctRows.values();
} else {
if (external != null && sort != null) {
// external sort
ResultExternal temp = external;
external = null;
temp.reset();
rows = Utils.newSmallArrayList();
// TODO use offset directly if possible
while (true) {
Value[] list = temp.next();
if (list == null) {
break;
}
if (external == null) {
createExternalResult();
}
rows.add(list);
if (rows.size() > maxMemoryRows) {
rowCount = external.addRows(rows);
rows.clear();
}
}
temp.close();
// the remaining data in rows is written in the following
// lines
}
}
}
if (external != null) { if (external != null) {
addRowsToDisk(); addRowsToDisk();
external.done();
} else { } else {
if (distinct) {
rows = distinctRows.values();
}
if (sort != null) { if (sort != null) {
if (offset > 0 || limit > 0) { if (offset > 0 || limit > 0) {
sort.sort(rows, offset, limit < 0 ? rows.size() : limit); sort.sort(rows, offset, limit < 0 ? rows.size() : limit);
...@@ -387,11 +351,64 @@ public class LocalResult implements ResultInterface, ResultTarget { ...@@ -387,11 +351,64 @@ public class LocalResult implements ResultInterface, ResultTarget {
} }
} }
} }
applyOffset(); applyOffsetAndLimit();
applyLimit();
reset(); reset();
} }
private void applyOffsetAndLimit() {
int offset = Math.max(this.offset, 0);
int limit = this.limit;
if (offset == 0 && limit < 0 || rowCount == 0) {
return;
}
boolean clearAll = offset >= rowCount || limit == 0;
if (!clearAll) {
int remaining = rowCount - offset;
limit = limit < 0 ? remaining : Math.min(remaining, limit);
if (offset == 0 && remaining <= limit) {
return;
}
} else {
limit = 0;
}
distinctRows = null;
rowCount = limit;
if (external == null) {
if (clearAll) {
rows.clear();
return;
}
// avoid copying the whole array for each row
rows = new ArrayList<>(rows.subList(offset, offset + limit));
} else {
if (clearAll) {
external.close();
external = null;
return;
}
trimExternal(offset, limit);
}
}
private void trimExternal(int offset, int limit) {
ResultExternal temp = external;
external = null;
temp.reset();
while (--offset >= 0) {
temp.next();
}
while (--limit >= 0) {
rows.add(temp.next());
if (rows.size() > maxMemoryRows) {
addRowsToDisk();
}
}
if (external != null) {
addRowsToDisk();
}
temp.close();
}
@Override @Override
public int getRowCount() { public int getRowCount() {
return rowCount; return rowCount;
...@@ -411,24 +428,6 @@ public class LocalResult implements ResultInterface, ResultTarget { ...@@ -411,24 +428,6 @@ public class LocalResult implements ResultInterface, ResultTarget {
this.limit = limit; this.limit = limit;
} }
private void applyLimit() {
if (limit < 0) {
return;
}
if (external == null) {
if (rows.size() > limit) {
rows = new ArrayList<>(rows.subList(0, limit));
rowCount = limit;
distinctRows = null;
}
} else {
if (limit < rowCount) {
rowCount = limit;
distinctRows = null;
}
}
}
@Override @Override
public boolean needToClose() { public boolean needToClose() {
return external != null; return external != null;
...@@ -502,31 +501,6 @@ public class LocalResult implements ResultInterface, ResultTarget { ...@@ -502,31 +501,6 @@ public class LocalResult implements ResultInterface, ResultTarget {
this.offset = offset; this.offset = offset;
} }
private void applyOffset() {
if (offset <= 0) {
return;
}
if (external == null) {
if (offset >= rows.size()) {
rows.clear();
rowCount = 0;
} else {
// avoid copying the whole array for each row
int remove = Math.min(offset, rows.size());
rows = new ArrayList<>(rows.subList(remove, rows.size()));
rowCount -= remove;
}
} else {
if (offset >= rowCount) {
rowCount = 0;
} else {
diskOffset = offset;
rowCount -= offset;
}
}
distinctRows = null;
}
@Override @Override
public String toString() { public String toString() {
return super.toString() + " columns: " + visibleColumnCount + return super.toString() + " columns: " + visibleColumnCount +
......
...@@ -42,11 +42,6 @@ public interface ResultExternal { ...@@ -42,11 +42,6 @@ public interface ResultExternal {
*/ */
int addRows(ArrayList<Value[]> rows); int addRows(ArrayList<Value[]> rows);
/**
* This method is called after all rows have been added.
*/
void done();
/** /**
* Close this object and delete the temporary file. * Close this object and delete the temporary file.
*/ */
......
...@@ -309,11 +309,6 @@ public class ResultTempTable implements ResultExternal { ...@@ -309,11 +309,6 @@ public class ResultTempTable implements ResultExternal {
} }
} }
@Override
public void done() {
// nothing to do
}
@Override @Override
public Value[] next() { public Value[] next() {
if (resultCursor == null) { if (resultCursor == null) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论