Mercurial > hg > monetdb-java
changeset 96:4a93f75c72c9 embedded
Java enums are compiled into objects, so changing the server responses parameters into integers gives an extra performance.
line wrap: on
line diff
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java +++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetConnection.java @@ -6,6 +6,7 @@ import nl.cwi.monetdb.mcl.connection.map import nl.cwi.monetdb.mcl.protocol.ProtocolException; import nl.cwi.monetdb.mcl.protocol.AbstractProtocol; import nl.cwi.monetdb.mcl.protocol.ServerResponses; +import nl.cwi.monetdb.mcl.protocol.StarterHeaders; import nl.cwi.monetdb.mcl.responses.*; import nl.cwi.monetdb.mcl.responses.DataBlockResponse; import nl.cwi.monetdb.mcl.responses.ResultSetResponse; @@ -131,7 +132,7 @@ public abstract class MonetConnection ex public abstract String getJDBCURL(); - public abstract void sendControlCommand(ControlCommands con, int data) throws SQLException; + public abstract void sendControlCommand(int con, int data) throws SQLException; public abstract ResponseList createResponseList(int fetchSize, int maxRows, int resultSetType, int resultSetConcurrency) throws SQLException; @@ -1251,7 +1252,8 @@ public abstract class MonetConnection ex try { protocol.writeNextQuery(language.getQueryTemplateIndex(0), command, language.getQueryTemplateIndex(1)); protocol.waitUntilPrompt(); - if (protocol.getCurrentServerResponseHeader() == ServerResponses.ERROR) { + int csrh = protocol.getCurrentServerResponseHeader(); + if (csrh == ServerResponses.ERROR) { String error = protocol.getRemainingStringLine(0); throw new SQLException(error.substring(6), error.substring(0, 5)); } @@ -1471,19 +1473,20 @@ public abstract class MonetConnection ex // go for new results protocol.fetchNextResponseData(); - ServerResponses nextResponse = protocol.getCurrentServerResponseHeader(); + int nextResponse = protocol.getCurrentServerResponseHeader(); IResponse res = null; while (nextResponse != ServerResponses.PROMPT) { // each response should start with a start of header (or error) switch (nextResponse) { - case SOHEADER: + case ServerResponses.SOHEADER: // make the response object, and fill it + int nextStartHeader = protocol.getNextStarterHeader(); try { - switch (protocol.getNextStarterHeader()) { - case Q_PARSE: - throw new ProtocolException("Q_PARSE header not allowed here", 1); - case Q_TABLE: - case Q_PREPARE: { + switch (nextStartHeader) { + case StarterHeaders.Q_PARSE: + throw new ProtocolException("Q_PARSE header not allowed here"); + case StarterHeaders.Q_TABLE: + case StarterHeaders.Q_PREPARE: { res = protocol.getNextResultSetResponse(MonetConnection.this, ResponseList.this, this.seqnr); ResultSetResponse rsreponse = (ResultSetResponse) res; @@ -1497,13 +1500,13 @@ public abstract class MonetConnection ex } } break; - case Q_UPDATE: + case StarterHeaders.Q_UPDATE: res = protocol.getNextUpdateResponse(); break; - case Q_SCHEMA: + case StarterHeaders.Q_SCHEMA: res = protocol.getNextSchemaResponse(); break; - case Q_TRANS: + case StarterHeaders.Q_TRANS: res = protocol.getNextAutoCommitResponse(); boolean isAutoCommit = ((AutoCommitResponse) res).isAutocommit(); @@ -1513,7 +1516,7 @@ public abstract class MonetConnection ex } MonetConnection.this.autoCommit = isAutoCommit; break; - case Q_BLOCK: { + case StarterHeaders.Q_BLOCK: { DataBlockResponse next = protocol.getNextDatablockResponse(rsresponses); if (next == null) { error = "M0M12!No ResultSetResponse for a DataBlock found"; @@ -1571,13 +1574,13 @@ public abstract class MonetConnection ex protocol.fetchNextResponseData(); nextResponse = protocol.getCurrentServerResponseHeader(); break; - case INFO: + case ServerResponses.INFO: addWarning(protocol.getRemainingStringLine(0), "01000"); // read the next line (can be prompt, new result, error, etc.) before we start the loop over protocol.fetchNextResponseData(); nextResponse = protocol.getCurrentServerResponseHeader(); break; - case ERROR: + case ServerResponses.ERROR: // read everything till the prompt (should be error) we don't know if we ignore some // garbage here... but the log should reveal that error = protocol.getRemainingStringLine(0);
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/ControlCommands.java +++ b/src/main/java/nl/cwi/monetdb/mcl/connection/ControlCommands.java @@ -8,14 +8,14 @@ package nl.cwi.monetdb.mcl.connection; -public enum ControlCommands { +public final class ControlCommands { /** Send autocommit statement */ - AUTO_COMMIT, + public static final int AUTO_COMMIT = 1; /** Set reply size for the server */ - REPLY_SIZE, + public static final int REPLY_SIZE = 2; /** Release a prepared statement data */ - RELEASE, + public static final int RELEASE = 3; /** Close a query */ - CLOSE + public static final int CLOSE = 4; }
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/SenderThread.java +++ b/src/main/java/nl/cwi/monetdb/mcl/connection/SenderThread.java @@ -29,20 +29,18 @@ import java.util.concurrent.locks.Reentr */ public class SenderThread extends Thread { - private enum SendThreadStatus { - /** The state WAIT represents this thread to be waiting for something to do */ - WAIT, - /** The state QUERY represents this thread to be executing a query */ - QUERY, - /** The state SHUTDOWN is the final state that ends this thread */ - SHUTDOWN - } + /** The state WAIT represents this thread to be waiting for something to do */ + private static final int WAIT = 1; + /** The state QUERY represents this thread to be executing a query */ + private static final int QUERY = 2; + /** The state SHUTDOWN is the final state that ends this thread */ + private static final int SHUTDOWN = 3; private String[] templ; private String query; private AbstractProtocol protocol; private String error; - private SendThreadStatus state = SendThreadStatus.WAIT; + private int state = SenderThread.WAIT; private final Lock sendLock = new ReentrantLock(); private final Condition queryAvailable = sendLock.newCondition(); private final Condition waiting = sendLock.newCondition(); @@ -64,14 +62,14 @@ public class SenderThread extends Thread this.sendLock.lock(); try { while (true) { - while (this.state == SendThreadStatus.WAIT) { + while (this.state == SenderThread.WAIT) { try { this.queryAvailable.await(); } catch (InterruptedException e) { // woken up, eh? } } - if (this.state == SendThreadStatus.SHUTDOWN) + if (this.state == SenderThread.SHUTDOWN) break; // state is QUERY here @@ -84,7 +82,7 @@ public class SenderThread extends Thread // update our state, and notify, maybe someone is waiting // for us in throwErrors - this.state = SendThreadStatus.WAIT; + this.state = SenderThread.WAIT; this.waiting.signal(); } } finally { @@ -103,13 +101,13 @@ public class SenderThread extends Thread public void runQuery(String[] templ, String query) throws SQLException { this.sendLock.lock(); try { - if (this.state != SendThreadStatus.WAIT) { + if (this.state != SenderThread.WAIT) { throw new SQLException("Sender Thread already in use or shutting down!", "M0M03"); } this.templ = templ; this.query = query; // let the thread know there is some work to do - this.state = SendThreadStatus.QUERY; + this.state = SenderThread.QUERY; this.queryAvailable.signal(); } finally { this.sendLock.unlock(); @@ -125,14 +123,14 @@ public class SenderThread extends Thread this.sendLock.lock(); try { // make sure the thread is in WAIT state, not QUERY - while (this.state == SendThreadStatus.QUERY) { + while (this.state == SenderThread.QUERY) { try { this.waiting.await(); } catch (InterruptedException e) { // just try again } } - if (this.state == SendThreadStatus.SHUTDOWN) + if (this.state == SenderThread.SHUTDOWN) this.error = "SendThread is shutting down"; } finally { this.sendLock.unlock(); @@ -145,7 +143,7 @@ public class SenderThread extends Thread */ public void shutdown() { sendLock.lock(); - state = SendThreadStatus.SHUTDOWN; + state = SenderThread.SHUTDOWN; sendLock.unlock(); this.interrupt(); // break any wait conditions }
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/mapi/MapiConnection.java +++ b/src/main/java/nl/cwi/monetdb/mcl/connection/mapi/MapiConnection.java @@ -201,25 +201,26 @@ public class MapiConnection extends Mone * @throws SQLException if an IO exception or a database error occurs */ @Override - public void sendControlCommand(ControlCommands con, int data) throws SQLException { + public void sendControlCommand(int con, int data) throws SQLException { String command = null; switch (con) { - case AUTO_COMMIT: + case ControlCommands.AUTO_COMMIT: command = "auto_commit " + ((data == 1) ? "1" : "0"); break; - case REPLY_SIZE: + case ControlCommands.REPLY_SIZE: command = "reply_size " + data; break; - case RELEASE: + case ControlCommands.RELEASE: command = "release " + data; break; - case CLOSE: + case ControlCommands.CLOSE: command = "close " + data; } try { protocol.writeNextQuery(language.getCommandTemplateIndex(0), command, language.getCommandTemplateIndex(1)); protocol.waitUntilPrompt(); - if (protocol.getCurrentServerResponseHeader() == ServerResponses.ERROR) { + int csrh = protocol.getCurrentServerResponseHeader(); + if (csrh == ServerResponses.ERROR) { String error = protocol.getRemainingStringLine(0); throw new SQLException(error.substring(6), error.substring(0, 5)); } @@ -267,19 +268,19 @@ public class MapiConnection extends Mone List<String> redirects = new ArrayList<>(); List<String> warns = new ArrayList<>(); String err = ""; - ServerResponses next; + int next; do { this.protocol.fetchNextResponseData(); next = this.protocol.getCurrentServerResponseHeader(); switch (next) { - case ERROR: + case ServerResponses.ERROR: err += "\n" + this.protocol.getRemainingStringLine(7); break; - case INFO: + case ServerResponses.INFO: warns.add(this.protocol.getRemainingStringLine(1)); break; - case REDIRECT: + case ServerResponses.REDIRECT: redirects.add(this.protocol.getRemainingStringLine(1)); } } while (next != ServerResponses.PROMPT);
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/AbstractProtocol.java +++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/AbstractProtocol.java @@ -24,9 +24,9 @@ public abstract class AbstractProtocol { public abstract void fetchNextResponseData() throws IOException; - public abstract ServerResponses getCurrentServerResponseHeader(); + public abstract int getCurrentServerResponseHeader(); - public abstract StarterHeaders getNextStarterHeader(); + public abstract int getNextStarterHeader(); public abstract ResultSetResponse getNextResultSetResponse(MonetConnection con, MonetConnection.ResponseList list, int seqnr) throws ProtocolException; @@ -42,8 +42,8 @@ public abstract class AbstractProtocol { public abstract DataBlockResponse getNextDatablockResponse(Map<Integer, ResultSetResponse> rsresponses) throws ProtocolException; - public abstract TableResultHeaders getNextTableHeader(String[] columnNames, int[] columnLengths, String[] types, - String[] tableNames) throws ProtocolException; + public abstract int getNextTableHeader(String[] columnNames, int[] columnLengths, String[] types, + String[] tableNames) throws ProtocolException; public abstract int parseTupleLines(int firstLineNumber, int[] typesMap, Object[] values, boolean[][] nulls) throws ProtocolException;
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/ServerResponses.java +++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/ServerResponses.java @@ -9,28 +9,28 @@ package nl.cwi.monetdb.mcl.protocol; /** - * This enum represents the possible stages of a query response by the server. + * This class represents the possible stages of a query response by the server. */ -public enum ServerResponses { +public final class ServerResponses { /* Please don't change the order */ /** "there is currently no line", or the the type is unknown is represented by UNKNOWN */ - UNKNOWN, + public static final int UNKNOWN = 0; /** a line starting with ! indicates ERROR */ - ERROR, + public static final int ERROR = 1; /** a line starting with % indicates HEADER */ - HEADER, + public static final int HEADER = 2; /** a line starting with [ indicates RESULT */ - RESULT, + public static final int RESULT = 3; /** a line which matches the pattern of prompt1 is a PROMPT */ - PROMPT, + public static final int PROMPT = 4; /** a line which matches the pattern of prompt2 is a MORE */ - MORE, + public static final int MORE = 5; /** a line starting with & indicates the start of a header block */ - SOHEADER, + public static final int SOHEADER = 6; /** a line starting with ^ indicates REDIRECT */ - REDIRECT, + public static final int REDIRECT = 7; /** a line starting with # indicates INFO */ - INFO + public static final int INFO = 8; }
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/StarterHeaders.java +++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/StarterHeaders.java @@ -9,28 +9,28 @@ package nl.cwi.monetdb.mcl.protocol; /** - * This enum lists the possible responses of a query by the server. Notice that Q_PARSE is not used by neither a MAPI or + * This class lists the possible responses of a query by the server. Notice that Q_PARSE is not used by neither a MAPI or * embedded connection, so it's here for completeness. */ -public enum StarterHeaders { +public final class StarterHeaders { /* Please don't change the order */ /** A parse response (not handled) */ - Q_PARSE, + public static final int Q_PARSE = 0; /** A tabular response (typical ResultSet) */ - Q_TABLE, + public static final int Q_TABLE = 1; /** A response to an update statement, contains number of affected rows and generated key-id */ - Q_UPDATE, + public static final int Q_UPDATE = 2; /** A response to a schema update */ - Q_SCHEMA, + public static final int Q_SCHEMA = 3; /** A response to a transaction statement (start, rollback, abort, commit) */ - Q_TRANS, + public static final int Q_TRANS = 4; /** A tabular response in response to a PREPARE statement containing information about the wildcard values that * need to be supplied */ - Q_PREPARE, + public static final int Q_PREPARE = 5; /** A tabular continuation response (for a ResultSet) */ - Q_BLOCK, + public static final int Q_BLOCK = 6; /** An unknown and unsupported response */ - Q_UNKNOWN + public static final int Q_UNKNOWN = 7; }
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/TableResultHeaders.java +++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/TableResultHeaders.java @@ -9,38 +9,23 @@ package nl.cwi.monetdb.mcl.protocol; /** - * This enum lists the result table headers returned by the server. + * This class lists the result table headers returned by the server. The integer values are used for the bitmap on the + * ResultSetResponse Class */ -public enum TableResultHeaders { +public final class TableResultHeaders { /* Please don't change the order */ + /** When an unknown table header is returned on a MAPI connection */ + public static final int UNKNOWN = 0; /** The column names */ - NAME(1), + public static final int NAME = 1; /** The column lengths */ - LENGTH(2), + public static final int LENGTH = 2; /** The column table and schemas names in format of schema.table */ - TABLE(4), + public static final int TABLE = 4; /** The SQL name of the MonetDB data type of the column */ - TYPE(8), + public static final int TYPE = 8; /** This header is returned by the JDBC embedded telling that it fetches all the previous headers at once */ - ALL(15), - /** When an unknown table header is returned on a MAPI connection */ - UNKNOWN(0); - - /** An integer value for the bitmap on the ResultSetResponse Class */ - private final int valueForBitMap; - - TableResultHeaders(int valueForBitMap) { - this.valueForBitMap = valueForBitMap; - } - - /** - * Returns the integer value for the bitmap. - * - * @return The integer value for the bitmap. - */ - public int getValueForBitMap() { - return valueForBitMap; - } + public static final int ALL = 15; }
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/newmapi/NewMapiProtocol.java +++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/newmapi/NewMapiProtocol.java @@ -21,8 +21,8 @@ import java.util.Map; public class NewMapiProtocol extends AbstractProtocol { @Override - public ServerResponses getCurrentServerResponseHeader() { - return null; + public int getCurrentServerResponseHeader() { + return 0; } @Override @@ -36,8 +36,8 @@ public class NewMapiProtocol extends Abs } @Override - public StarterHeaders getNextStarterHeader() { - return null; + public int getNextStarterHeader() { + return 0; } @Override @@ -61,8 +61,8 @@ public class NewMapiProtocol extends Abs } @Override - public TableResultHeaders getNextTableHeader(String[] columnNames, int[] columnLengths, String[] types, String[] tableNames) throws ProtocolException { - return null; + public int getNextTableHeader(String[] columnNames, int[] columnLengths, String[] types, String[] tableNames) throws ProtocolException { + return 0; } @Override
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiProtocol.java +++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiProtocol.java @@ -13,8 +13,6 @@ import nl.cwi.monetdb.mcl.connection.map import nl.cwi.monetdb.mcl.protocol.ProtocolException; import nl.cwi.monetdb.mcl.protocol.AbstractProtocol; import nl.cwi.monetdb.mcl.protocol.ServerResponses; -import nl.cwi.monetdb.mcl.protocol.StarterHeaders; -import nl.cwi.monetdb.mcl.protocol.TableResultHeaders; import nl.cwi.monetdb.mcl.responses.AutoCommitResponse; import nl.cwi.monetdb.mcl.responses.UpdateResponse; import nl.cwi.monetdb.mcl.responses.DataBlockResponse; @@ -26,7 +24,7 @@ import java.util.Map; public class OldMapiProtocol extends AbstractProtocol { - private ServerResponses currentServerResponseHeader = ServerResponses.UNKNOWN; + private int currentServerResponseHeader = ServerResponses.UNKNOWN; private final OldMapiSocket socket; @@ -45,7 +43,7 @@ public class OldMapiProtocol extends Abs } @Override - public ServerResponses getCurrentServerResponseHeader() { + public int getCurrentServerResponseHeader() { return currentServerResponseHeader; } @@ -82,7 +80,7 @@ public class OldMapiProtocol extends Abs } @Override - public StarterHeaders getNextStarterHeader() { + public int getNextStarterHeader() { return OldMapiStartOfHeaderParser.GetNextStartHeaderOnOldMapi(this); } @@ -125,7 +123,7 @@ public class OldMapiProtocol extends Abs } @Override - public TableResultHeaders getNextTableHeader(String[] columnNames, int[] columnLengths, String[] types, String[] tableNames) throws ProtocolException { + public int getNextTableHeader(String[] columnNames, int[] columnLengths, String[] types, String[] tableNames) throws ProtocolException { return OldMapiTableHeaderParser.GetNextTableHeader(this.lineBuffer, columnNames, columnLengths, types, tableNames); }
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiServerResponseParser.java +++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiServerResponseParser.java @@ -12,8 +12,8 @@ import nl.cwi.monetdb.mcl.protocol.Serve final class OldMapiServerResponseParser { - static ServerResponses ParseOldMapiServerResponse(OldMapiProtocol protocol) { - ServerResponses res; + static int ParseOldMapiServerResponse(OldMapiProtocol protocol) { + int res; switch (protocol.lineBuffer.get()) { case '!': res = ServerResponses.ERROR;
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiStartOfHeaderParser.java +++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiStartOfHeaderParser.java @@ -13,8 +13,8 @@ import nl.cwi.monetdb.mcl.protocol.Start final class OldMapiStartOfHeaderParser { - static StarterHeaders GetNextStartHeaderOnOldMapi(OldMapiProtocol protocol) { - StarterHeaders res; + static int GetNextStartHeaderOnOldMapi(OldMapiProtocol protocol) { + int res; switch (protocol.lineBuffer.get()) { case '0': res = StarterHeaders.Q_PARSE;
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTableHeaderParser.java +++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTableHeaderParser.java @@ -15,9 +15,9 @@ import java.nio.CharBuffer; final class OldMapiTableHeaderParser { - static TableResultHeaders GetNextTableHeader(CharBuffer lineBuffer, String[] columnNames, int[] columnLengths, + static int GetNextTableHeader(CharBuffer lineBuffer, String[] columnNames, int[] columnLengths, String[] types, String[] tableNames) throws ProtocolException { - TableResultHeaders res = TableResultHeaders.UNKNOWN; + int res = TableResultHeaders.UNKNOWN; int currentLength = lineBuffer.limit(); char[] array = lineBuffer.array();
--- a/src/main/java/nl/cwi/monetdb/mcl/responses/DataBlockResponse.java +++ b/src/main/java/nl/cwi/monetdb/mcl/responses/DataBlockResponse.java @@ -76,7 +76,8 @@ public class DataBlockResponse implement */ @Override public void addLines(AbstractProtocol protocol) throws ProtocolException { - if (protocol.getCurrentServerResponseHeader() != ServerResponses.RESULT) { + int csrh = protocol.getCurrentServerResponseHeader(); + if (csrh != ServerResponses.RESULT) { throw new ProtocolException("protocol violation: unexpected line in data block: " + protocol.getRemainingStringLine(0)); }
--- a/src/main/java/nl/cwi/monetdb/mcl/responses/ResultSetResponse.java +++ b/src/main/java/nl/cwi/monetdb/mcl/responses/ResultSetResponse.java @@ -295,14 +295,16 @@ public class ResultSetResponse implement public void addLines(AbstractProtocol protocol) throws ProtocolException { if (this.isSet >= IS_SET_FINAL_VALUE) { this.resultBlocks[0].addLines(protocol); - } else if (protocol.getCurrentServerResponseHeader() != ServerResponses.HEADER) { - throw new ProtocolException("header expected, got: " + protocol.getRemainingStringLine(0)); } else { - TableResultHeaders next = con.getProtocol().getNextTableHeader(this.name, this.columnLengths, this.type, - this.tableNames); - this.isSet |= next.getValueForBitMap(); - if(this.isSet >= IS_SET_FINAL_VALUE) { - this.populateJdbcSQLTypesArray(); //VERY IMPORTANT to populate the JDBC types array + int csrh = protocol.getCurrentServerResponseHeader(); + if (csrh != ServerResponses.HEADER) { + throw new ProtocolException("header expected, got: " + protocol.getRemainingStringLine(0)); + } else { + int next = con.getProtocol().getNextTableHeader(this.name, this.columnLengths, this.type, this.tableNames); + this.isSet |= next; + if (this.isSet >= IS_SET_FINAL_VALUE) { + this.populateJdbcSQLTypesArray(); //VERY IMPORTANT to populate the JDBC types array + } } } }
--- a/src/main/java/nl/cwi/monetdb/merovingian/Control.java +++ b/src/main/java/nl/cwi/monetdb/merovingian/Control.java @@ -179,7 +179,7 @@ public class Control { protocol.writeNextQuery(null,database + " " + command, "\n"); ArrayList<String> l = new ArrayList<>(); protocol.waitUntilPrompt(); - ServerResponses next = protocol.getCurrentServerResponseHeader(); + int next = protocol.getCurrentServerResponseHeader(); String line = protocol.getRemainingStringLine(0); if (next == ServerResponses.ERROR)
--- a/src/main/java/nl/cwi/monetdb/util/SQLRestore.java +++ b/src/main/java/nl/cwi/monetdb/util/SQLRestore.java @@ -52,7 +52,7 @@ public class SQLRestore { public void run() { AbstractProtocol protocol = _is.getProtocol(); - ServerResponses next; + int next; String line; try { while (true) { @@ -62,7 +62,7 @@ public class SQLRestore { if (line == null) break; switch (next) { - case ERROR: + case ServerResponses.ERROR: _errorMessage = line; _errorState.set(true); return;