crunch-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "mac champion (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (CRUNCH-414) The CSV file source needs to be a little more robust when handling multi-line CSV files
Date Thu, 26 Jun 2014 14:56:25 GMT

    [ https://issues.apache.org/jira/browse/CRUNCH-414?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14044727#comment-14044727
] 

mac champion commented on CRUNCH-414:
-------------------------------------

Oh I see, so it's not just spawning tons of StringBuilder objects to be garbage collected
later. Got it. 
How about this?
{code}
        StringBuilder stringBuilder = null;
        do {
            totalBytesConsumed += readFileLine(inputText);
            // a line has been read. We need to see if we're still in quotes and tack
            // on a newline if so
            if (currentlyInQuotes && !endOfFile) {
                if (stringBuilder == null) {
                    stringBuilder = new StringBuilder();
                }
                // If we end up in a multi-line record, we need to build it. Grab what's inputText
and append it to the
                // builder, append a newline, and set inputText to the result after it's built.
                stringBuilder.append(inputText.toString()).append('\n');
            }

            if (totalBytesConsumed > maximumRecordSize || totalBytesConsumed > Integer.MAX_VALUE)
{
                LOGGER.error("Possibly malformed file encountered. First line of record: "
+ inputText.toString());
                throw new IOException("Possibly malformed file encountered. Check log statements
for more information");
            }
        } while (currentlyInQuotes && !endOfFile);

        if (stringBuilder != null) {
            input.set(stringBuilder.toString());
        } else {
            input.set(inputText);
        }

        return (int) totalBytesConsumed;
    }
{code}
This way, a StringBuilder isn't even created unless a multi-line record has definitely been
encountered. Then, it's reused until the record is fully read. At the end, if a StringBuilder
has been created, its value is used. Otherwise, the line in inputText is used. 

I'll work on making the threshold configurable later, I think it will have to be injected
into the constructor. 

> The CSV file source needs to be a little more robust when handling multi-line CSV files
> ---------------------------------------------------------------------------------------
>
>                 Key: CRUNCH-414
>                 URL: https://issues.apache.org/jira/browse/CRUNCH-414
>             Project: Crunch
>          Issue Type: Improvement
>          Components: Core
>    Affects Versions: 0.8.3
>            Reporter: mac champion
>            Assignee: mac champion
>            Priority: Minor
>              Labels: csv, csvparser
>             Fix For: 0.8.4
>
>   Original Estimate: 336h
>  Remaining Estimate: 336h
>
> Brandon Inman recently reported an undesriable behavior in the CSV file source group
of files. Currently, the CSVLineReader, if reading a malformed CSV file, can enter a state
where it is perpetually waiting for an end-quote character. As he put it, "Malformed files
are malformed files and should probably fail in some regard, but a hang is obviously undesirable."

> Essentially, the CSVLineReader needs to be tweaked in such a way that an informative
exception is thrown after some threshold is reached, instead of basically just hanging. 



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Mime
View raw message