예제 #1
0
    void fillBuffer () {
        size_t n = sizeof(buffer);
        char* ptr = reinterpret_cast<char*>(&buffer);

        while (0 < n) {
            ssize_t r = TRI_READ(fd, ptr, n);

            if (r == 0) {
                LOGGER_FATAL << "read on random device failed: nothing read";
                THROW_INTERNAL_ERROR("read on random device failed");
            }
            else if (errno == EWOULDBLOCK) {
                LOGGER_INFO << "not enough entropy (got " << (sizeof(buffer) - n) << " bytes), switching to pseudo-random";
                break;
            }
            else if (r < 0) {
                LOGGER_FATAL << "read on random device failed: " << strerror(errno);
                THROW_INTERNAL_ERROR("read on random device failed");
            }

            ptr += r;
            n -= r;

            rseed = buffer[0];

            LOGGER_TRACE << "using seed " << rseed;
        }

        if (0 < n) {
            unsigned long seed = (unsigned long) time(0);

#ifdef TRI_HAVE_GETTIMEOFDAY
            struct timeval tv;
            int result = gettimeofday(&tv, 0);

            seed ^= static_cast<unsigned long>(tv.tv_sec);
            seed ^= static_cast<unsigned long>(tv.tv_usec);
            seed ^= static_cast<unsigned long>(result);
#endif

            seed ^= static_cast<unsigned long>(Thread::currentProcessId());

            mersenneDevice.seed(rseed ^ (uint32_t) seed);

            while (0 < n) {
                *ptr++ = randomGenerator();
                --n;
            }
        }

        pos = 0;
    }
예제 #2
0
      void fillBuffer () {
        size_t n = sizeof(buffer);
        char* ptr = reinterpret_cast<char*>(&buffer);

        while (0 < n) {
          ssize_t r = TRI_READ(fd, ptr, n);

          if (r == 0) {
            LOGGER_FATAL_AND_EXIT("read on random device failed: nothing read");
          }
          else if (r < 0) {
            LOGGER_FATAL_AND_EXIT("read on random device failed: " << strerror(errno));
          }

          ptr += r;
          n -= r;
        }

        pos = 0;
      }
예제 #3
0
      string slurp (string const& filename) {
        int fd = TRI_OPEN(filename.c_str(), O_RDONLY);

        if (fd == -1) {
          TRI_set_errno(errno);
          THROW_FILE_OPEN_ERROR("open", filename, "O_RDONLY", errno);
        }

        char buffer[10240];
        StringBuffer result(TRI_CORE_MEM_ZONE);

        while (true) {
          ssize_t n = TRI_READ(fd, buffer, sizeof(buffer));

          if (n == 0) {
            break;
          }

          if (n < 0) {
            TRI_set_errno(TRI_ERROR_SYS_ERROR);

            LOG_TRACE("read failed for '%s' with %s and result %d on fd %d", 
                      filename.c_str(),
                      strerror(errno),
                      (int) n,
                      fd);

            TRI_CLOSE(fd);
            THROW_FILE_FUNC_ERROR("read", "", errno);
          }

          result.appendText(buffer, n);
        }

        TRI_CLOSE(fd);

        string r(result.c_str(), result.length());

        return r;
      }
예제 #4
0
      void fillBuffer () {
        size_t n = sizeof(buffer);
        char* ptr = reinterpret_cast<char*>(&buffer);

        while (0 < n) {
          ssize_t r = TRI_READ(fd, ptr, (TRI_read_t) n);

          if (r == 0) {
            LOG_FATAL_AND_EXIT("read on random device failed: nothing read");
          }
          else if (errno == EWOULDBLOCK) {
            LOG_INFO("not enough entropy (got %d), switching to pseudo-random", (int) (sizeof(buffer) - n));
            break;
          }
          else if (r < 0) {
            LOG_FATAL_AND_EXIT("read on random device failed: %s", strerror(errno));
          }

          ptr += r;
          n -= r;

          rseed = buffer[0];

          LOG_TRACE("using seed %lu", (long unsigned int) rseed);
        }

        if (0 < n) {
          std::mt19937 engine;
          unsigned long seed = RandomDevice::getSeed();
          engine.seed((uint32_t) (rseed ^ (uint32_t) seed));

          while (0 < n) {
            *ptr++ = engine();
            --n;
          }
        }

        pos = 0;
      }
예제 #5
0
      void fillBuffer () {
        size_t n = sizeof(buffer);
        char* ptr = reinterpret_cast<char*>(&buffer);

        while (0 < n) {
          ssize_t r = TRI_READ(fd, ptr, n);

          if (r == 0) {
            LOGGER_FATAL_AND_EXIT("read on random device failed: nothing read");
          }
          else if (errno == EWOULDBLOCK) {
            LOGGER_INFO("not enough entropy (got " << (sizeof(buffer) - n) << " bytes), switching to pseudo-random");
            break;
          }
          else if (r < 0) {
            LOGGER_FATAL_AND_EXIT("read on random device failed: " << strerror(errno));
          }

          ptr += r;
          n -= r;

          rseed = buffer[0];

          LOGGER_TRACE("using seed " << rseed);
        }

        if (0 < n) {
          unsigned long seed = RandomDevice::getSeed();
          TRI_SeedMersenneTwister((uint32_t) (rseed ^ (uint32_t) seed));

          while (0 < n) {
            *ptr++ = TRI_Int32MersenneTwister();
            --n;
          }
        }

        pos = 0;
      }
예제 #6
0
      void slurp (string const& filename, StringBuffer& result) {
        int fd = TRI_OPEN(filename.c_str(), O_RDONLY);

        if (fd == -1) {
          THROW_FILE_OPEN_ERROR("open", filename, "O_RDONLY", errno);
        }
        
        // reserve space in the output buffer
        off_t fileSize = size(filename);
        if (fileSize > 0) {
          result.reserve((size_t) fileSize);
        }

        char buffer[10240];

        while (true) {
          ssize_t n = TRI_READ(fd, buffer, sizeof(buffer));

          if (n == 0) {
            break;
          }

          if (n < 0) {
            TRI_CLOSE(fd);
            LOG_TRACE("read failed for '%s' with %s and result %d on fd %d",
                      filename.c_str(),
                      strerror(errno),
                      (int) n,
                      fd); 
            THROW_FILE_FUNC_ERROR("read", "", errno);
          }

          result.appendText(buffer, n);
        }

        TRI_CLOSE(fd);
      }
예제 #7
0
    bool ImportHelper::importDelimited (string const& collectionName,
                                        string const& fileName,
                                        DelimitedImportType typeImport) {
      _collectionName = collectionName;
      _firstLine = "";
      _numberLines = 0;
      _numberOk = 0;
      _numberError = 0;
      _outputBuffer.clear();
      _lineBuffer.clear();
      _errorMessage = "";
      _hasError = false;

      // read and convert
      int fd;
      int64_t totalLength;

      if (fileName == "-") {
        // we don't have a filesize
        totalLength = 0;
        fd = STDIN_FILENO;
      }
      else {
        // read filesize
        totalLength = TRI_SizeFile(fileName.c_str());
        fd = TRI_OPEN(fileName.c_str(), O_RDONLY);

        if (fd < 0) {
          _errorMessage = TRI_LAST_ERROR_STR;
          return false;
        }
      }

      // progress display control variables
      int64_t totalRead = 0;
      double nextProgress = ProgressStep;

      size_t separatorLength;
      char* separator = TRI_UnescapeUtf8StringZ(TRI_UNKNOWN_MEM_ZONE, _separator.c_str(), _separator.size(), &separatorLength);

      if (separator == 0) {
        if (fd != STDIN_FILENO) {
          TRI_CLOSE(fd);
        }

        _errorMessage = "out of memory";
        return false;
      }

      TRI_csv_parser_t parser;

      TRI_InitCsvParser(&parser,
                        TRI_UNKNOWN_MEM_ZONE,
                        ProcessCsvBegin,
                        ProcessCsvAdd,
                        ProcessCsvEnd);

      TRI_SetSeparatorCsvParser(&parser, separator[0]);

      // in csv, we'll use the quote char if set
      // in tsv, we do not use the quote char
      if (typeImport == ImportHelper::CSV && _quote.size() > 0) {
        TRI_SetQuoteCsvParser(&parser, _quote[0], true);
      }
      else {
        TRI_SetQuoteCsvParser(&parser, '\0', false);
      }
      parser._dataAdd = this;
      _rowOffset = 0;
      _rowsRead  = 0;

      char buffer[32768];

      while (! _hasError) {
        ssize_t n = TRI_READ(fd, buffer, sizeof(buffer));

        if (n < 0) {
          TRI_Free(TRI_UNKNOWN_MEM_ZONE, separator);
          TRI_DestroyCsvParser(&parser);
          if (fd != STDIN_FILENO) {
            TRI_CLOSE(fd);
          }
          _errorMessage = TRI_LAST_ERROR_STR;
          return false;
        }
        else if (n == 0) {
          break;
        }

        totalRead += (int64_t) n;
        reportProgress(totalLength, totalRead, nextProgress);

        TRI_ParseCsvString2(&parser, buffer, n);
      }

      if (_outputBuffer.length() > 0) {
        sendCsvBuffer();
      }

      TRI_DestroyCsvParser(&parser);
      TRI_Free(TRI_UNKNOWN_MEM_ZONE, separator);

      if (fd != STDIN_FILENO) {
        TRI_CLOSE(fd);
      }

      _outputBuffer.clear();
      return !_hasError;
    }
예제 #8
0
    bool ImportHelper::importJson (const string& collectionName, const string& fileName) {
      _collectionName = collectionName;
      _firstLine = "";
      _numberLines = 0;
      _numberOk = 0;
      _numberError = 0;
      _outputBuffer.clear();
      _errorMessage = "";
      _hasError = false;

      // read and convert
      int fd;
      int64_t totalLength;

      if (fileName == "-") {
        // we don't have a filesize
        totalLength = 0;
        fd = STDIN_FILENO;
      }
      else {
        // read filesize
        totalLength = TRI_SizeFile(fileName.c_str());
        fd = TRI_OPEN(fileName.c_str(), O_RDONLY);

        if (fd < 0) {
          _errorMessage = TRI_LAST_ERROR_STR;
          return false;
        }
      }

      bool isArray = false;
      bool checkedFront = false;

      // progress display control variables
      int64_t totalRead = 0;
      double nextProgress = ProgressStep;

      static const int BUFFER_SIZE = 32768;

      while (! _hasError) {
        // reserve enough room to read more data
        if (_outputBuffer.reserve(BUFFER_SIZE) == TRI_ERROR_OUT_OF_MEMORY) {
          _errorMessage = TRI_errno_string(TRI_ERROR_OUT_OF_MEMORY);

          if (fd != STDIN_FILENO) {
            TRI_CLOSE(fd);
          }
          return false;
        }

        // read directly into string buffer
        ssize_t n = TRI_READ(fd, _outputBuffer.end(), BUFFER_SIZE - 1);

        if (n < 0) {
          _errorMessage = TRI_LAST_ERROR_STR;
          if (fd != STDIN_FILENO) {
            TRI_CLOSE(fd);
          }
          return false;
        }
        else if (n == 0) {
          // we're done
          break;
        }

        // adjust size of the buffer by the size of the chunk we just read
        _outputBuffer.increaseLength(n);

        if (! checkedFront) {
          // detect the import file format (single lines with individual JSON objects
          // or a JSON array with all documents)
          char const* p = _outputBuffer.begin();
          char const* e = _outputBuffer.end();

          while (p < e &&
                 (*p == ' ' || *p == '\r' || *p == '\n' || *p == '\t' || *p == '\f' || *p == '\b')) {
            ++p;
          }

          isArray = (*p == '[');
          checkedFront = true;
        }

        totalRead += (int64_t) n;
        reportProgress(totalLength, totalRead, nextProgress);

        if (_outputBuffer.length() > _maxUploadSize) {
          if (isArray) {
            if (fd != STDIN_FILENO) {
              TRI_CLOSE(fd);
            }
            _errorMessage = "import file is too big. please increase the value of --batch-size (currently " + StringUtils::itoa(_maxUploadSize) + ")";
            return false;
          }

          // send all data before last '\n'
          char const* first = _outputBuffer.c_str();
          char* pos = (char*) memrchr(first, '\n', _outputBuffer.length());

          if (pos != 0) {
            size_t len = pos - first + 1;
            sendJsonBuffer(first, len, isArray);
            _outputBuffer.erase_front(len);
          }
        }
      }

      if (_outputBuffer.length() > 0) {
        sendJsonBuffer(_outputBuffer.c_str(), _outputBuffer.length(), isArray);
      }

      _numberLines = _numberError + _numberOk;

      if (fd != STDIN_FILENO) {
        TRI_CLOSE(fd);
      }

      _outputBuffer.clear();
      return ! _hasError;
    }
예제 #9
0
    bool ImportHelper::importJson (const string& collectionName, const string& fileName) {
      _collectionName = collectionName;
      _firstLine = "";
      _numberLines = 0;
      _numberOk = 0;
      _numberError = 0;
      _outputBuffer.clear();
      _errorMessage = "";
      _hasError = false;

      // read and convert
      int fd;
      int64_t totalLength;

      if (fileName == "-") {
        // we don't have a filesize
        totalLength = 0;
        fd = STDIN_FILENO;
      }
      else {
        // read filesize
        totalLength = TRI_SizeFile(fileName.c_str());
        fd = TRI_OPEN(fileName.c_str(), O_RDONLY);
      
        if (fd < 0) {
          _errorMessage = TRI_LAST_ERROR_STR;
          return false;
        }
      }

      char buffer[32768];
      bool isArray = false;
      bool checkedFront = false;

      // progress display control variables
      int64_t totalRead = 0;
      double nextProgress = ProgressStep;

      while (! _hasError) {
        ssize_t n = TRI_READ(fd, buffer, sizeof(buffer));

        if (n < 0) {
          _errorMessage = TRI_LAST_ERROR_STR;
          if (fd != STDIN_FILENO) {
            TRI_CLOSE(fd);
          }
          return false;
        }
        else if (n == 0) {
          // we're done
          break;
        }

        if (! checkedFront) {
          // detect the import file format (single lines with individual JSON objects
          // or a JSON array with all documents)
          const string firstChar = StringUtils::lTrim(string(buffer, n), "\r\n\t\f\b ").substr(0, 1);
          isArray = (firstChar == "[");
          checkedFront = true;
        }

        _outputBuffer.appendText(buffer, n);

        totalRead += (int64_t) n;
        reportProgress(totalLength, totalRead, nextProgress);

        if (_outputBuffer.length() > _maxUploadSize) {
          if (isArray) {
            if (fd != STDIN_FILENO) {
              TRI_CLOSE(fd);
            }
            _errorMessage = "import file is too big.";
            return false;
          }

          // send all data before last '\n'
          const char* first = _outputBuffer.c_str();
          char* pos = (char*) memrchr(first, '\n', _outputBuffer.length());

          if (pos != 0) {
            size_t len = pos - first + 1;
            sendJsonBuffer(first, len, isArray);
            _outputBuffer.erase_front(len);
          }
        }
      }

      if (_outputBuffer.length() > 0) {
        sendJsonBuffer(_outputBuffer.c_str(), _outputBuffer.length(), isArray);
      }

      _numberLines = _numberError + _numberOk;

      if (fd != STDIN_FILENO) {
        TRI_CLOSE(fd);
      }

      _outputBuffer.clear();
      return ! _hasError;
    }