Fixing out of memory errors during CSV data import


I have tried to import one CSV data file about 1GB into a VoltDB cluster with 2 nodes both having 16GB RAM and got out of memory errors.

After examining the details of CSV import process, I found that when the CSV data is not very clear (such as many duplicate records) and may cause many failures (such as CONSTRAINT VIOLATION). The failed queue used to hold individual rows for insertion will be soon fully filled too many requests that consume too much memory on the machine. 

This PR is intended to fix this problem. I also noticed that invalid rows are kept in memory until data insertion is done and then are flushed in to a file on disk. It also consumes too much memory space when there are too many invalid rows. So this PR makes modification on that behavior to progressively flush invalid rows into file.

Looking at the code, I don't think it needs to check `m_errorInfo.containsKey(metaData.lineNumber)` below, because `handleError()` should only be called once for the same error.

Without the need to check for existence, `m_errorInfo` doesn't have to be a map anymore. You can create a simple class that wraps the line number as well as the error information and change `m_errorInfo` to `LinkedBlockingQueue` of that class type.

In terms of performance, it won't be an issue if the disk can keep up and there aren't a lot of errors being generated. If there are a lot of partitions in the cluster, the throughput could be much higher. When a lot of errors are being generated in that case, some partitions may see hiccups on the network thread due to fsyncing the files.