/*
     * This method processes a block of rows in a single invocation.
     *
     * The inputs are retrieved via arg_reader
     * The outputs are returned via arg_writer
     */
    virtual void processBlock(ServerInterface &srvInterface,
                              BlockReader &arg_reader,
                              BlockWriter &res_writer)
    {
        // Basic error checking
        if (arg_reader.getNumCols() != 2)
            vt_report_error(0, "Function only accept 2 arguments, but %zu provided",
                            arg_reader.getNumCols());

        // While we have inputs to process
        do {
            // Get a copy of the input string
            const std::string& patternStr = arg_reader.getStringRef(0).str();
            const std::string& inStr = arg_reader.getStringRef(1).str();

            size_t m = patternStr.size();
            size_t n = inStr.size();
            size_t d[m+1][n+1];
            for (size_t i = 0; i <= m; ++i)
                d[i][0] = i; // the distance of any first string to an empty second string
            for (size_t j = 0; j <= n; ++j)
                d[0][j] = j; // the distance of any second string to an empty first string

            for (size_t j = 1; j <= n; ++j)
                for (size_t i = 1; i <= m; ++i)
                {
                    if (patternStr[i-1] == inStr[j-1])
                        d[i][j] = d[i-1][j-1];       // no operation required
                    else
                    {
                        d[i][j] = std::min(std::min(d[i-1][j] + 1,  // a deletion
                                                    d[i][j-1] + 1),  // an insertion
                                           d[i-1][j-1] + 1); // a substitution
                    }
                }

            res_writer.setInt(d[m][n]);
            res_writer.next();
        } while (arg_reader.next());
    }