Ejemplo n.º 1
0
uint32_t TRI_UInt32String (char const* str) {
  uint32_t result;
  char* endptr;

#if defined(TRI_HAVE_STRTOUL_R)
  struct reent buffer;
#elif defined(TRI_HAVE__STRTOUL_R)
  struct reent buffer;
#endif

  TRI_set_errno(TRI_ERROR_NO_ERROR);

#if defined(TRI_HAVE_STRTOUL_R)
  result = strtoul_r(&buffer, str, &endptr, 10);
#elif defined(TRI_HAVE__STRTOUL_R)
  result = _strtoul_r(&buffer, str, &endptr, 10);
#else
  result = strtoul(str, &endptr, 10);
#endif

  while (isspace(*endptr)) {
    ++endptr;
  }

  if (*endptr != '\0') {
    TRI_set_errno(TRI_ERROR_ILLEGAL_NUMBER);
  }

  if (errno == ERANGE && (result == 0 || result == UINT32_MAX)) {
    TRI_set_errno(TRI_ERROR_NUMERIC_OVERFLOW);
  }

  return result;
}
Ejemplo n.º 2
0
bool VelocyPackHelper::velocyPackToFile(char const* filename,
                                        VPackSlice const& slice,
                                        bool syncFile) {
  std::string const tmp = std::string(filename) + ".tmp";

  // remove a potentially existing temporary file
  if (TRI_ExistsFile(tmp.c_str())) {
    TRI_UnlinkFile(tmp.c_str());
  }

  int fd = TRI_CREATE(tmp.c_str(), O_CREAT | O_TRUNC | O_EXCL | O_RDWR | TRI_O_CLOEXEC,
                      S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);

  if (fd < 0) {
    TRI_set_errno(TRI_ERROR_SYS_ERROR);
    LOG(ERR) << "cannot create json file '" << tmp << "': " << TRI_LAST_ERROR_STR;
    return false;
  }

  if (!PrintVelocyPack(fd, slice, true)) {
    TRI_CLOSE(fd);
    TRI_set_errno(TRI_ERROR_SYS_ERROR);
    LOG(ERR) << "cannot write to json file '" << tmp << "': " << TRI_LAST_ERROR_STR;
    TRI_UnlinkFile(tmp.c_str());
    return false;
  }

  if (syncFile) {
    LOG(TRACE) << "syncing tmp file '" << tmp << "'";

    if (!TRI_fsync(fd)) {
      TRI_CLOSE(fd);
      TRI_set_errno(TRI_ERROR_SYS_ERROR);
      LOG(ERR) << "cannot sync saved json '" << tmp << "': " << TRI_LAST_ERROR_STR;
      TRI_UnlinkFile(tmp.c_str());
      return false;
    }
  }

  int res = TRI_CLOSE(fd);

  if (res < 0) {
    TRI_set_errno(TRI_ERROR_SYS_ERROR);
    LOG(ERR) << "cannot close saved file '" << tmp << "': " << TRI_LAST_ERROR_STR;
    TRI_UnlinkFile(tmp.c_str());
    return false;
  }

  res = TRI_RenameFile(tmp.c_str(), filename);

  if (res != TRI_ERROR_NO_ERROR) {
    TRI_set_errno(res);
    LOG(ERR) << "cannot rename saved file '" << tmp << "' to '" << filename << "': " << TRI_LAST_ERROR_STR;
    TRI_UnlinkFile(tmp.c_str());

    return false;
  }

  return true;
}
Ejemplo n.º 3
0
TRI_replication_applier_t* TRI_CreateReplicationApplier (TRI_vocbase_t* vocbase) {
  TRI_replication_applier_t* applier;
  int res;

  applier = TRI_Allocate(TRI_CORE_MEM_ZONE, sizeof(TRI_replication_applier_t), false);

  if (applier == NULL) {
    return NULL;
  }
  
  TRI_InitConfigurationReplicationApplier(&applier->_configuration);
  TRI_InitStateReplicationApplier(&applier->_state);

  res = LoadConfiguration(vocbase, &applier->_configuration);
  
  if (res != TRI_ERROR_NO_ERROR && 
      res != TRI_ERROR_FILE_NOT_FOUND) {
    TRI_set_errno(res);
    TRI_DestroyStateReplicationApplier(&applier->_state);
    TRI_DestroyConfigurationReplicationApplier(&applier->_configuration);
    TRI_Free(TRI_CORE_MEM_ZONE, applier);

    return NULL;
  }

  res = TRI_LoadStateReplicationApplier(vocbase, &applier->_state);

  if (res != TRI_ERROR_NO_ERROR && 
      res != TRI_ERROR_FILE_NOT_FOUND) {
    TRI_set_errno(res);
    TRI_DestroyStateReplicationApplier(&applier->_state);
    TRI_DestroyConfigurationReplicationApplier(&applier->_configuration);
    TRI_Free(TRI_CORE_MEM_ZONE, applier);

    return NULL;
  }
  
  TRI_InitReadWriteLock(&applier->_statusLock);
  TRI_InitSpin(&applier->_threadLock);
  TRI_InitCondition(&applier->_runStateChangeCondition);

  applier->_vocbase      = vocbase;
  applier->_databaseName = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, vocbase->_name);
  
  SetTerminateFlag(applier, false); 

  assert(applier->_databaseName != NULL);

  TRI_SetProgressReplicationApplier(applier, "applier created", false);
  
  return applier;
}
Ejemplo n.º 4
0
char* TRI_GetDirectoryCollection (char const* path,
                                  const TRI_col_info_t* const parameter) {
  char* filename;

  assert(path);
  assert(parameter);

  // shape collections use just the name, e.g. path/SHAPES
  if (parameter->_type == TRI_COL_TYPE_SHAPE) {
    filename = TRI_Concatenate2File(path, parameter->_name);
  }
  // other collections use the collection identifier
  else if (TRI_IS_DOCUMENT_COLLECTION(parameter->_type)) {
    char* tmp1;
    char* tmp2;

    tmp1 = TRI_StringUInt64(parameter->_cid);
    if (tmp1 == NULL) {
      TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);

      return NULL;
    }

    tmp2 = TRI_Concatenate2String("collection-", tmp1);
    if (tmp2 == NULL) {
      TRI_FreeString(TRI_CORE_MEM_ZONE, tmp1);

      TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);

      return NULL;
    }

    filename = TRI_Concatenate2File(path, tmp2);
    TRI_FreeString(TRI_CORE_MEM_ZONE, tmp1);
    TRI_FreeString(TRI_CORE_MEM_ZONE, tmp2);
  }
  // oops, unknown collection type
  else {
    TRI_set_errno(TRI_ERROR_ARANGO_UNKNOWN_COLLECTION_TYPE);
    return NULL;
  }

  if (filename == NULL) {
    TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
  }

  // might be NULL
  return filename;
}
Ejemplo n.º 5
0
bool TRI_StartThread (TRI_thread_t* thread,
                      TRI_tid_t* threadId,
                      char const* name,
                      void (*starter)(void*),
                      void* data) {
  thread_data_t* d = static_cast<thread_data_t*>(TRI_Allocate(TRI_CORE_MEM_ZONE, sizeof(thread_data_t), false));

  d->starter = starter;
  d->_data = data;
  d->_name = TRI_DuplicateString(name);

  int rc = pthread_create(thread, 0, &ThreadStarter, d);

  if (rc != 0) {
    TRI_set_errno(TRI_ERROR_SYS_ERROR);
    LOG_ERROR("could not start thread: %s", strerror(errno));

    TRI_Free(TRI_CORE_MEM_ZONE, d);
    return false;
  }

  if (threadId != nullptr) {
    *threadId = (TRI_tid_t) *thread;
  }

  return true;
}
Ejemplo n.º 6
0
static int CopyDocument (TRI_sim_collection_t* collection,
                         TRI_df_marker_t const* marker,
                         TRI_df_marker_t** result,
                         TRI_voc_fid_t* fid) {
  TRI_datafile_t* journal;
  TRI_voc_size_t total;

  // find and select a journal
  total = marker->_size;
  journal = SelectCompactor(collection, total, result);

  if (journal == NULL) {
    collection->base.base._lastError = TRI_set_errno(TRI_ERROR_ARANGO_NO_JOURNAL);
    return false;
  }

  *fid = journal->_fid;

  // and write marker and blob
  return TRI_WriteElementDatafile(journal,
                                  *result,
                                  marker, marker->_size,
                                  NULL, 0,
                                  false);
}
Ejemplo n.º 7
0
int TRI_AddLinkedArray (TRI_linked_array_t* array, void const* data) {
  TRI_linked_list_entry_t* entry;
  TRI_linked_list_entry_t* found;

  // create entry
  entry = TRI_Allocate(array->_memoryZone, sizeof(TRI_linked_list_entry_t), false);

  if (entry == NULL) {
    return TRI_ERROR_OUT_OF_MEMORY;
  }

  entry->_data = data;

  // insert to lookup table
  found = TRI_InsertElementAssociativePointer(&array->_array, entry, true);

  if (TRI_errno() == TRI_ERROR_OUT_OF_MEMORY) {
    TRI_Free(array->_memoryZone, entry);
    return TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
  }

  // this should not happen
  if (found != NULL) {
    TRI_RemoveLinkedList(&array->_list, found);
    TRI_Free(array->_memoryZone, found);
  }

  // add element at the beginning
  TRI_AddLinkedList(&array->_list, entry);

  return TRI_ERROR_NO_ERROR;
}
Ejemplo n.º 8
0
TRI_shape_access_t* TRI_ShapeAccessor (TRI_shaper_t* shaper,
                                       TRI_shape_sid_t sid,
                                       TRI_shape_pid_t pid) {
  TRI_shape_access_t* accessor;
  bool ok;

  accessor = TRI_Allocate(shaper->_memoryZone, sizeof(TRI_shape_access_t), false);

  if (accessor == NULL) {
    TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
    return NULL;
  }

  accessor->_sid = sid;
  accessor->_pid = pid;
  accessor->_code = NULL;
  accessor->_memoryZone = shaper->_memoryZone;

  ok = BytecodeShapeAccessor(shaper, accessor);

  if (ok) {
    return accessor;
  }

  TRI_FreeShapeAccessor(accessor);
  return NULL;
}
TRI_replication_applier_t* TRI_CreateReplicationApplier (TRI_server_t* server,
                                                         TRI_vocbase_t* vocbase) {
  TRI_replication_applier_t* applier = new TRI_replication_applier_t(server, vocbase);

  if (applier == nullptr) {
    return nullptr;
  }
  
  TRI_InitConfigurationReplicationApplier(&applier->_configuration);
  TRI_InitStateReplicationApplier(&applier->_state);

  if (vocbase->_type == TRI_VOCBASE_TYPE_NORMAL) {
    int res = LoadConfiguration(vocbase, &applier->_configuration);

    if (res != TRI_ERROR_NO_ERROR &&
        res != TRI_ERROR_FILE_NOT_FOUND) {
      TRI_set_errno(res);
      TRI_DestroyStateReplicationApplier(&applier->_state);
      TRI_DestroyConfigurationReplicationApplier(&applier->_configuration);
      delete applier;

      return nullptr;
    }

    res = TRI_LoadStateReplicationApplier(vocbase, &applier->_state);

    if (res != TRI_ERROR_NO_ERROR &&
        res != TRI_ERROR_FILE_NOT_FOUND) {
      TRI_set_errno(res);
      TRI_DestroyStateReplicationApplier(&applier->_state);
      TRI_DestroyConfigurationReplicationApplier(&applier->_configuration);
      delete applier;

      return nullptr;
    }
  }

  SetTerminateFlag(applier, false);

  TRI_ASSERT(applier->_databaseName != nullptr);

  TRI_SetProgressReplicationApplier(applier, "applier created", false);

  return applier;
}
Ejemplo n.º 10
0
void* TRI_AllocateZ (TRI_memory_zone_t* zone, uint64_t n, bool set, char const* file, int line) {
#else
void* TRI_Allocate (TRI_memory_zone_t* zone, uint64_t n, bool set) {
#endif
  char* m;

#ifdef TRI_ENABLE_MAINTAINER_MODE
  CheckSize(n, file, line);

  m = MALLOC_WRAPPER(zone, (size_t) n + sizeof(uintptr_t));
#else
  m = MALLOC_WRAPPER(zone, (size_t) n);
#endif

  if (m == NULL) {
    if (zone->_failable) {
      TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
      return NULL;
    }

    if (CoreReserve == NULL) {
      fprintf(stderr,
              "FATAL: failed to allocate %llu bytes for memory zone %d" ZONE_DEBUG_LOCATION ", giving up!\n",
              (unsigned long long) n,
              (int) zone->_zid
              ZONE_DEBUG_PARAMS);
      TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
    }

    free(CoreReserve);
    CoreReserve = NULL;

    fprintf(stderr,
            "failed to allocate %llu bytes for memory zone %d" ZONE_DEBUG_LOCATION ", retrying!\n",
            (unsigned long long) n,
            (int) zone->_zid
            ZONE_DEBUG_PARAMS);

#ifdef TRI_ENABLE_MAINTAINER_MODE
    return TRI_AllocateZ(zone, n, set, file, line);
#else
    return TRI_Allocate(zone, n, set);
#endif
  }

#ifdef TRI_ENABLE_MAINTAINER_MODE
  else if (set) {
    memset(m, 0, (size_t) n + sizeof(uintptr_t));
  }
  else {
    // prefill with 0xA5 (magic value, same as Valgrind will use)
    memset(m, 0xA5, (size_t) n + sizeof(uintptr_t));
  }
#else
  else if (set) {
Ejemplo n.º 11
0
void* TRI_InsertKeyAssociativePointer (TRI_associative_pointer_t* array,
                                       void const* key,
                                       void* element,
                                       bool overwrite) {
  uint64_t hash;
  uint64_t i;
  void* old;

  // check for out-of-memory
  if (array->_nrAlloc == array->_nrUsed) {
    TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
    return NULL;
  }

  // compute the hash
  hash = array->hashKey(array, key);
  i = hash % array->_nrAlloc;

#ifdef TRI_INTERNAL_STATS
  // update statistics
  array->_nrAdds++;
#endif

  // search the table
  while (array->_table[i] != NULL && ! array->isEqualKeyElement(array, key, array->_table[i])) {
    i = TRI_IncModU64(i, array->_nrAlloc);
#ifdef TRI_INTERNAL_STATS
    array->_nrProbesA++;
#endif
  }

  old = array->_table[i];

  // if we found an element, return
  if (old != NULL) {
    if (overwrite) {
      array->_table[i] = element;
    }

    return old;
  }

  // add a new element to the associative array
  array->_table[i] = element;
  array->_nrUsed++;

  // if we were adding and the table is more than half full, extend it
  if (array->_nrAlloc < 2 * array->_nrUsed) {
    ResizeAssociativePointer(array, (uint32_t) (2 * array->_nrAlloc) + 1);
  }

  return NULL;
}
Ejemplo n.º 12
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;
      }
Ejemplo n.º 13
0
void* TRI_InsertKeyAssociativeSynced (TRI_associative_synced_t* array,
                                      void const* key,
                                      void* element) {
  uint64_t hash;
  uint64_t i;
  void* old;

  // check for out-of-memory
  if (array->_nrAlloc == array->_nrUsed) {
    TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
    return NULL;
  }

  // compute the hash
  hash = array->hashKey(array, key);
  i = hash % array->_nrAlloc;

#ifdef TRI_INTERNAL_STATS
  // update statistics
  array->_nrAdds++;
#endif

  // search the table
  TRI_WriteLockReadWriteLock(&array->_lock);

  while (array->_table[i] != NULL && ! array->isEqualKeyElement(array, key, array->_table[i])) {
    i = (i + 1) % array->_nrAlloc;
#ifdef TRI_INTERNAL_STATS
    array->_nrProbesA++;
#endif
  }

  old = array->_table[i];

  // if we found an element, return
  if (old != NULL) {
    TRI_WriteUnlockReadWriteLock(&array->_lock);
    return old;
  }

  // add a new element to the associative array
  array->_table[i] = element;
  array->_nrUsed++;

  // if we were adding and the table is more than half full, extend it
  if (array->_nrAlloc < 2 * array->_nrUsed) {
    ResizeAssociativeSynced(array);
  }

  TRI_WriteUnlockReadWriteLock(&array->_lock);
  return NULL;
}
Ejemplo n.º 14
0
void* TRI_AllocateZ(TRI_memory_zone_t* zone, uint64_t n, bool set,
                    char const* file, int line) {
#else
void* TRI_Allocate(TRI_memory_zone_t* zone, uint64_t n, bool set) {
#endif
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
  CheckSize(n, file, line);
#endif
  char* m = static_cast<char*>(MALLOC_WRAPPER(zone, (size_t)n));

  if (m == nullptr) {
    if (zone->_failable) {
      TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
      return nullptr;
    }

    if (CoreReserve == nullptr) {
      fprintf(stderr,
              "FATAL: failed to allocate %llu bytes for core mem zone "
              ZONE_DEBUG_LOCATION ", giving up!\n",
              (unsigned long long)n ZONE_DEBUG_PARAMS);
      TRI_EXIT_FUNCTION(EXIT_FAILURE, nullptr);
    }

    free(CoreReserve);
    CoreReserve = nullptr;

    fprintf(
        stderr,
        "failed to allocate %llu bytes for core mem zone" ZONE_DEBUG_LOCATION
        ", retrying!\n",
        (unsigned long long)n ZONE_DEBUG_PARAMS);

#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
    return TRI_AllocateZ(zone, n, set, file, line);
#else
    return TRI_Allocate(zone, n, set);
#endif
  }

  if (set) {
    memset(m, 0, (size_t)n);
  }
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
  else {
    // prefill with 0xA5 (magic value, same as Valgrind will use)
    memset(m, 0xA5, (size_t)n);
  }
#endif

  return m;
}
Ejemplo n.º 15
0
double TRI_DoubleString (char const* str) {
  double result;
  char* endptr;

  TRI_set_errno(TRI_ERROR_NO_ERROR);

  result = strtod(str, &endptr);

  while (isspace(*endptr)) {
    ++endptr;
  }

  if (*endptr != '\0') {
    TRI_set_errno(TRI_ERROR_ILLEGAL_NUMBER);
  }

  if (errno == ERANGE && (result == HUGE_VAL || result == -HUGE_VAL || result == 0)) {
    TRI_set_errno(TRI_ERROR_NUMERIC_OVERFLOW);
  }

  return result;
}
Ejemplo n.º 16
0
uint64_t TRI_UInt64String (char const* str) {
  uint64_t result;
  char* endptr;

#if defined(TRI_HAVE_STRTOULL_R)
  struct reent buffer;
#elif defined(TRI_HAVE__STRTOULL_R)
  struct reent buffer;
#endif

  TRI_set_errno(TRI_ERROR_NO_ERROR);

#if defined(TRI_HAVE_STRTOULL_R)
  result = strtoull_r(&buffer, str, &endptr, 10);
#elif defined(TRI_HAVE__STRTOULL_R)
  result = _strtoull_r(&buffer, str, &endptr, 10);
#elif defined(TRI_HAVE_STRTOUI64)
  result = _strtoui64(str, &endptr, 10);
#elif defined(TRI_HAVE_STRTOULL)
  result = strtoull(str, &endptr, 10);
#else
#warning cannot convert string to int64
#endif

  while (isspace(*endptr)) {
    ++endptr;
  }

  if (*endptr != '\0') {
    TRI_set_errno(TRI_ERROR_ILLEGAL_NUMBER);
  }

  if (errno == ERANGE && (result == 0 || result == UINT64_MAX)) {
    TRI_set_errno(TRI_ERROR_NUMERIC_OVERFLOW);
  }

  return result;
}
Ejemplo n.º 17
0
void* TRI_InsertKeyAssociativeSynced (TRI_associative_synced_t* array,
                                      void const* key,
                                      void* element,
                                      bool overwrite) {
  uint64_t hash;
  uint64_t i;
  void* old;

  // compute the hash
  hash = array->hashKey(array, key);

  // search the table
  TRI_WriteLockReadWriteLock(&array->_lock);

  // check for out-of-memory
  if (array->_nrAlloc == array->_nrUsed && ! overwrite) {
    TRI_WriteUnlockReadWriteLock(&array->_lock);
    TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
    return NULL;
  }

  i = hash % array->_nrAlloc;

  while (array->_table[i] != NULL && ! array->isEqualKeyElement(array, key, array->_table[i])) {
    i = TRI_IncModU64(i, array->_nrAlloc);
  }

  old = array->_table[i];

  // if we found an element, return
  if (old != NULL) {
    if (overwrite) {
      array->_table[i] = element;
    }
    TRI_WriteUnlockReadWriteLock(&array->_lock);
    return old;
  }

  // add a new element to the associative array
  array->_table[i] = element;
  array->_nrUsed++;

  // if we were adding and the table is more than half full, extend it
  if (array->_nrAlloc < 2 * array->_nrUsed) {
    ResizeAssociativeSynced(array, (uint32_t) (2 * array->_nrAlloc + 1));
  }

  TRI_WriteUnlockReadWriteLock(&array->_lock);
  return NULL;
}
Ejemplo n.º 18
0
bool TRI_InsertKeyAssociativeArray (TRI_associative_array_t* array, void* key, void* element, bool overwrite) {
  uint64_t hash;
  uint64_t i;

  // check for out-of-memory
  if (array->_nrAlloc == array->_nrUsed) {
    TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
    return false;
  }

  // compute the hash
  hash = array->hashKey(array, key);
  i = hash % array->_nrAlloc;

#ifdef TRI_INTERNAL_STATS
  // update statistics
  array->_nrAdds++;
#endif

  // search the table
  while (! array->isEmptyElement(array, array->_table + i * array->_elementSize)
         && ! array->isEqualKeyElement(array, key, array->_table + i * array->_elementSize)) {
    i = TRI_IncModU64(i, array->_nrAlloc);
#ifdef TRI_INTERNAL_STATS
    array->_nrProbesA++;
#endif
  }

  // if we found an element, return
  if (! array->isEmptyElement(array, array->_table + i * array->_elementSize)) {
    if (overwrite) {
      memcpy(array->_table + i * array->_elementSize, element, array->_elementSize);
    }

    return false;
  }

  // add a new element to the associative array
  memcpy(array->_table + i * array->_elementSize, element, array->_elementSize);
  array->_nrUsed++;

  // if we were adding and the table is more than half full, extend it
  if (array->_nrAlloc < 2 * array->_nrUsed) {
    ResizeAssociativeArray(array, (uint32_t) (2 * array->_nrAlloc + 1));
  }

  return true;
}
Ejemplo n.º 19
0
static int CopyMarker (TRI_document_collection_t* document,
                       TRI_datafile_t* compactor,
                       TRI_df_marker_t const* marker,
                       TRI_df_marker_t** result) {
  int res;

  res = TRI_ReserveElementDatafile(compactor, marker->_size, result, 0);

  if (res != TRI_ERROR_NO_ERROR) {
    document->base.base._lastError = TRI_set_errno(TRI_ERROR_ARANGO_NO_JOURNAL);

    return TRI_ERROR_ARANGO_NO_JOURNAL;
  }

  return TRI_WriteElementDatafile(compactor, *result, marker, marker->_size, false);
}
Ejemplo n.º 20
0
void TRI_InsertVector (TRI_vector_t* vector, void const* element, size_t position) {
  char* newBuffer;
  size_t newSize;
  
  // ...........................................................................
  // Check and see if we need to extend the vector
  // ...........................................................................
  
  if (vector->_length >= vector->_capacity || position >= vector->_length) {
    newSize = (size_t) (1 + (vector->_growthFactor * vector->_capacity));

    if (position >= newSize) {
      newSize = position + 1;
    }
  
    newBuffer = (char*) TRI_Allocate(vector->_memoryZone, newSize * vector->_elementSize, false);

    if (newBuffer == NULL) {
      TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
      return;
    }

    vector->_capacity = newSize;

    if (vector->_buffer != NULL) {
      memcpy(newBuffer, vector->_buffer, vector->_length * vector->_elementSize);
      TRI_Free(vector->_memoryZone, vector->_buffer);
    }

    vector->_buffer = newBuffer;
  }

  if (position < vector->_length) {
    memmove(vector->_buffer + (vector->_elementSize * (position + 1)), 
            vector->_buffer + (vector->_elementSize * position), 
            vector->_elementSize * (vector->_length - position)
           );
    vector->_length += 1;
  }  
  else {
    vector->_length = position + 1;
  }
  
  memcpy(vector->_buffer + (vector->_elementSize * position), element, vector->_elementSize);
}
Ejemplo n.º 21
0
TRI_headers_t* TRI_CreateSimpleHeaders (size_t headerSize) {
  simple_headers_t* headers = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(simple_headers_t), false);

  if (headers == NULL) {
    TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
    return NULL;
  }

  headers->base.request = RequestSimpleHeaders;
  headers->base.verify  = VerifySimpleHeaders;
  headers->base.release = ReleaseSimpleHeaders;

  headers->_freelist = NULL;
  headers->_headerSize = headerSize;

  TRI_InitVectorPointer(&headers->_blocks, TRI_UNKNOWN_MEM_ZONE);

  return &headers->base;
}
Ejemplo n.º 22
0
static TRI_doc_mptr_t* RequestSimpleHeaders (TRI_headers_t* h) {
  simple_headers_t* headers = (simple_headers_t*) h;
  char const* header;
  union { TRI_doc_mptr_t const* c; TRI_doc_mptr_t* h; } c;

  if (headers->_freelist == NULL) {
    char* begin;
    char* ptr;
    size_t blockSize;

    blockSize = GetBlockSize(headers->_blocks._length);

    begin = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, blockSize * headers->_headerSize, false);

    // out of memory
    if (begin == NULL) {
      TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
      return NULL;
    }

    ptr = begin + headers->_headerSize * (blockSize - 1);

    header = NULL;

    for (;  begin <= ptr;  ptr -= headers->_headerSize) {
      ClearSimpleHeaders((TRI_doc_mptr_t*) ptr, headers->_headerSize);
      ((TRI_doc_mptr_t*) ptr)->_data = header;
      header = ptr;
    }

    headers->_freelist = (TRI_doc_mptr_t*) header;

    TRI_PushBackVectorPointer(&headers->_blocks, begin);
  }

  c.c = headers->_freelist;
  headers->_freelist = c.c->_data;

  c.h->_data = NULL;
  return c.h;
}
Ejemplo n.º 23
0
static int HashIndex_insert (TRI_hash_index_t* hashIndex,
                             TRI_hash_index_element_t* element) {
  TRI_index_search_value_t key;
  int res;

  res = FillIndexSearchValueByHashIndexElement(hashIndex, &key, element);
  
  if (res != TRI_ERROR_NO_ERROR) {
    // out of memory
    return res;
  }

  res = TRI_InsertKeyHashArray(&hashIndex->_hashArray, &key, element, false);
  if (key._values != NULL) {
    TRI_Free(TRI_UNKNOWN_MEM_ZONE, key._values);
  }

  if (res == TRI_RESULT_KEY_EXISTS) {
    return TRI_set_errno(TRI_ERROR_ARANGO_UNIQUE_CONSTRAINT_VIOLATED);
  }

  return res;
}
Ejemplo n.º 24
0
static TRI_doc_mptr_t CreateJson (TRI_doc_collection_t* collection,
                                  TRI_df_marker_type_e type,
                                  TRI_json_t const* json,
                                  void const* data,
                                  bool reuseId,
                                  bool release) {
  TRI_shaped_json_t* shaped;
  TRI_doc_mptr_t result;
  TRI_voc_did_t did = 0;
  TRI_voc_rid_t rid = 0;
 
  shaped = TRI_ShapedJsonJson(collection->_shaper, json);

  if (shaped == 0) {
    collection->base._lastError = TRI_set_errno(TRI_ERROR_ARANGO_SHAPER_FAILED);
    memset(&result, 0, sizeof(result));
    return result;
  }
  
  if (reuseId && json != NULL && json->_type == TRI_JSON_ARRAY) {
    TRI_json_t* id = TRI_LookupArrayJson((TRI_json_t*) json, "_id");
    TRI_json_t* rev = TRI_LookupArrayJson((TRI_json_t*) json, "_rev");

    if (id != NULL && id->_type == TRI_JSON_NUMBER && 
        rev != NULL && rev->_type == TRI_JSON_NUMBER) {
      // read existing document id and revision id from document
      did = (TRI_voc_did_t) id->_value._number;
      rid = (TRI_voc_rid_t) rev->_value._number;
    }
  }

  result = collection->create(collection, type, shaped, data, did, rid, release);

  TRI_FreeShapedJson(collection->_shaper, shaped);

  return result;
}
Ejemplo n.º 25
0
TRI_shape_access_t* TRI_ShapeAccessor (TRI_shaper_t* shaper,
                                       TRI_shape_sid_t sid,
                                       TRI_shape_pid_t pid) {
  TRI_shape_access_t* accessor = static_cast<TRI_shape_access_t*>(TRI_Allocate(shaper->_memoryZone, sizeof(TRI_shape_access_t), false));

  if (accessor == nullptr) {
    TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
    return nullptr;
  }

  accessor->_sid = sid;
  accessor->_pid = pid;
  accessor->_code = nullptr;
  accessor->_memoryZone = shaper->_memoryZone;

  bool ok = BytecodeShapeAccessor(shaper, accessor);

  if (ok) {
    return accessor;
  }

  TRI_FreeShapeAccessor(accessor);
  return nullptr;
}
Ejemplo n.º 26
0
static TRI_doc_mptr_t UpdateJson (TRI_doc_collection_t* collection,
                                  TRI_json_t const* json,
                                  TRI_voc_did_t did,
                                  TRI_voc_rid_t rid,
                                  TRI_voc_rid_t* oldRid,
                                  TRI_doc_update_policy_e policy,
                                  bool release) {
  TRI_shaped_json_t* shaped;
  TRI_doc_mptr_t result;

  shaped = TRI_ShapedJsonJson(collection->_shaper, json);

  if (shaped == 0) {
    collection->base._lastError = TRI_set_errno(TRI_ERROR_ARANGO_SHAPER_FAILED);
    memset(&result, 0, sizeof(result));
    return result;
  }

  result = collection->update(collection, shaped, did, rid, oldRid, policy, release);

  TRI_FreeShapedJson(collection->_shaper, shaped);

  return result;
}
Ejemplo n.º 27
0
bool TRI_SaveJson (char const* filename, TRI_json_t const* object) {
  bool ok;
  char* tmp;
  int fd;
  int res;
  ssize_t m;

  tmp = TRI_Concatenate2String(filename, ".tmp");

  if (tmp == NULL) {
    return false;
  }

  fd = TRI_CREATE(tmp, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);

  if (fd < 0) {
    TRI_set_errno(TRI_ERROR_SYS_ERROR);
    LOG_ERROR("cannot create json file '%s': '%s'", tmp, TRI_LAST_ERROR_STR);
    TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);
    return false;
  }

  ok = TRI_PrintJson(fd, object);

  if (! ok) {
    TRI_set_errno(TRI_ERROR_SYS_ERROR);
    LOG_ERROR("cannot write to json file '%s': '%s'", tmp, TRI_LAST_ERROR_STR);
    TRI_UnlinkFile(tmp);
    TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);
    return false;
  }

  m = TRI_WRITE(fd, "\n", 1);

  if (m <= 0) {
    TRI_set_errno(TRI_ERROR_SYS_ERROR);
    LOG_ERROR("cannot write to json file '%s': '%s'", tmp, TRI_LAST_ERROR_STR);
    TRI_UnlinkFile(tmp);
    TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);
    return false;
  }

  ok = TRI_fsync(fd);

  if (! ok) {
    TRI_set_errno(TRI_ERROR_SYS_ERROR);
    LOG_ERROR("cannot sync saved json '%s': '%s'", tmp, TRI_LAST_ERROR_STR);
    TRI_UnlinkFile(tmp);
    TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);
    return false;
  }

  res = TRI_CLOSE(fd);

  if (res < 0) {
    TRI_set_errno(TRI_ERROR_SYS_ERROR);
    LOG_ERROR("cannot close saved file '%s': '%s'", tmp, TRI_LAST_ERROR_STR);
    TRI_UnlinkFile(tmp);
    TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);
    return false;
  }

  res = TRI_RenameFile(tmp, filename);

  if (res != TRI_ERROR_NO_ERROR) {
    LOG_ERROR("cannot rename saved file '%s' to '%s': '%s'", tmp, filename, TRI_LAST_ERROR_STR);
    TRI_UnlinkFile(tmp);
    TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);

    return res;
  }

  TRI_FreeString(TRI_CORE_MEM_ZONE, tmp);
  return ok;
}
Ejemplo n.º 28
0
bool TRI_InitPQueue (TRI_pqueue_t* pq, size_t initialCapacity, size_t itemSize, bool reverse,
                     void (*clearStorage) (struct TRI_pqueue_s*, void*),
                     uint64_t (*getStorage) (struct TRI_pqueue_s*, void*),
                     bool (*isLess) (struct TRI_pqueue_s*, void*, void*),
                     void (*updateStorage) (struct TRI_pqueue_s*, void*, uint64_t pos)) {

  if (pq == NULL) {
    return false;
  }

  // ..........................................................................
  // Assign the call back functions
  // ..........................................................................


  // ..........................................................................
  // This callback is used to remove any memory which may be used as part of
  // the storage within the array _items. Callback required since we do not
  // know if there is any internal structure.
  // ..........................................................................
  pq->clearStoragePQ = clearStorage;


  // ..........................................................................
  // Returns the position within the _items array the element is.
  // Currently this simply is used to perform a consistency check.
  // ..........................................................................
  pq->getStoragePQ = getStorage;


  // ..........................................................................
  // The actual comparison function which returns true if left item is
  // less than right item (otherwise false).
  // ..........................................................................
  pq->isLessPQ  = isLess;


  // ..........................................................................
  // Stores the position of the element within the _items array. Its purpose
  // is to allow the storage position to be located independent of the
  // priority queue _items array.
  // ..........................................................................
  pq->updateStoragePQ = updateStorage;


  // ..........................................................................
  // Assign the element size
  // ..........................................................................
  pq->_base._itemSize = itemSize;


  // ..........................................................................
  // Initialise invalid access counters
  // ..........................................................................
  pq->_base._nrFalseRemoves = 0;
  pq->_base._nrFalseAdds    = 0;


  // ..........................................................................
  // Set the capacity and assign memory for storage
  // ..........................................................................
  pq->_base._capacity = initialCapacity;
  pq->_base._items    = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, pq->_base._itemSize * pq->_base._capacity, true);
  if (pq->_base._items == NULL) {
    TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
    LOG_ERROR("out of memory when creating priority queue storage");
    return false;
  }


  // ..........................................................................
  // initialise the number of items stored
  // ..........................................................................
  pq->_base._count = 0;

  // ..........................................................................
  // Determines if the pq should be reversed
  // ..........................................................................
  pq->_base._reverse = reverse;


  // ..........................................................................
  // The static call back functions to query, modifiy the pq
  // ..........................................................................
  pq->add    = AddPQueue;
  pq->remove = RemovePQueue;
  pq->top    = TopPQueue;

  return true;
}
Ejemplo n.º 29
0
static int ExtractCurrentFile (unzFile uf,
                               void* buffer,
                               const size_t bufferSize,
                               const char* outPath,
                               const bool skipPaths,
                               const bool overwrite,
                               const char* password) {
  char filenameInZip[256];
  char* filenameWithoutPath;
  char* fullPath;
  char* p;
  FILE *fout;
  unz_file_info64 fileInfo;

  if (unzGetCurrentFileInfo64(uf, &fileInfo, filenameInZip, sizeof(filenameInZip), NULL, 0, NULL, 0) != UNZ_OK) {
    return TRI_ERROR_INTERNAL;
  }

  p = filenameWithoutPath = filenameInZip;

  // get the file name without any path prefix
  while (*p != '\0') {
    if (*p == '/' || *p == '\\') {
      filenameWithoutPath = p + 1;
    }

    p++;
  }
  
  // found a directory
  if (*filenameWithoutPath == '\0') {
    if (! skipPaths) {
      fullPath = TRI_Concatenate2File(outPath, filenameInZip);
      TRI_CreateRecursiveDirectory(fullPath);
      TRI_Free(TRI_CORE_MEM_ZONE, fullPath);
    }
  }

  // found a file
  else {
    const char* writeFilename;

    if (! skipPaths) {
      writeFilename = filenameInZip;
    }
    else {
      writeFilename = filenameWithoutPath;
    }

    if (unzOpenCurrentFilePassword(uf, password) != UNZ_OK) {
      return TRI_ERROR_INTERNAL;
    }

    // prefix the name from the zip file with the path specified
    fullPath = TRI_Concatenate2File(outPath, writeFilename);
    
    if (! overwrite && TRI_ExistsFile(fullPath)) {
      return TRI_ERROR_INTERNAL;
    }

    // try to write the outfile
    fout = fopen(fullPath, "wb");

    // cannot write to outfile. this may be due to the target directory missing
    if (fout == NULL && ! skipPaths && filenameWithoutPath != (char*) filenameInZip) {
      char* d;

      char c = *(filenameWithoutPath - 1);
      *(filenameWithoutPath - 1) = '\0';

      // create target directory recursively
      d = TRI_Concatenate2File(outPath, filenameInZip);
      TRI_CreateRecursiveDirectory(d);
      TRI_Free(TRI_CORE_MEM_ZONE, d);

      *(filenameWithoutPath - 1) = c;

      // try again
      fout = fopen(fullPath, "wb");
    }
    
    TRI_Free(TRI_CORE_MEM_ZONE, fullPath);

    if (fout == NULL) {
      return TRI_ERROR_CANNOT_WRITE_FILE;
    }

    while (true) {
      int result = unzReadCurrentFile(uf, buffer, bufferSize);

      if (result < 0) {
        fclose(fout);

        return TRI_ERROR_INTERNAL;
      }

      if (result > 0) {
        if (fwrite(buffer, result, 1, fout) != 1) {
          fclose(fout);

          return TRI_set_errno(TRI_ERROR_SYS_ERROR);
        }
      }
      else {
        assert(result == 0);
        break;
      }
    }

    fclose(fout);
  }

  unzCloseCurrentFile(uf);
  
  return TRI_ERROR_NO_ERROR;
}
Ejemplo n.º 30
0
int TRI_ZipFile (const char* filename, 
                 const char* dir,
                 TRI_vector_string_t const* files,
                 const char* password) {
  void* buffer;
  size_t bufferSize;
  zipFile zf;
#ifdef USEWIN32IOAPI
  zlib_filefunc64_def ffunc;
#endif
  size_t i, n;
  int res;

  if (TRI_ExistsFile(filename)) {
    return TRI_ERROR_CANNOT_OVERWRITE_FILE;
  }

  bufferSize = 16384;
  buffer = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, bufferSize, false);

  if (buffer == NULL) {
    return TRI_ERROR_OUT_OF_MEMORY;
  }

#ifdef USEWIN32IOAPI
  fill_win32_filefunc64A(&ffunc);
  zf = zipOpen2_64(filename, 0, NULL, &ffunc);
#else
  zf = zipOpen64(filename, 0);
#endif

  if (zf == NULL) {
    TRI_Free(TRI_UNKNOWN_MEM_ZONE, buffer);

    return ZIP_ERRNO;
  }

  res = TRI_ERROR_NO_ERROR;

  n = files->_length;
  for (i = 0; i < n; ++i) {
    FILE* fin;
    char* file;
    char* fullfile;
    char* saveName;
    zip_fileinfo zi;
    uint32_t crc;
    int isLarge;

    file = TRI_AtVectorString(files, i);

    if (*dir == '\0') {
      fullfile = TRI_DuplicateString(file);
    }
    else {
      fullfile = TRI_Concatenate2File(dir, file);
    }

    memset(&zi, 0, sizeof(zi));

    res = TRI_Crc32File(fullfile, &crc);

    if (res != TRI_ERROR_NO_ERROR) {
      break;
    }

    isLarge = (TRI_SizeFile(file) > 0xFFFFFFFFLL);
              
    saveName = file;

    while (*saveName == '\\' || *saveName == '/') {
      ++saveName;
    }

    if (zipOpenNewFileInZip3_64(zf,
                                saveName,
                                &zi,
                                NULL,
                                0,
                                NULL,
                                0,
                                NULL, /* comment*/
                                Z_DEFLATED,
                                Z_DEFAULT_COMPRESSION,
                                0,
                                -MAX_WBITS, 
                                DEF_MEM_LEVEL, 
                                Z_DEFAULT_STRATEGY,
                                password,
                                (unsigned long) crc, 
                                isLarge) != ZIP_OK) {
    }

    fin = fopen(fullfile, "rb");
    TRI_FreeString(TRI_CORE_MEM_ZONE, fullfile);

    if (fin == NULL) {
      break;
    }

    while (true) {
      int sizeRead;

      sizeRead = (int) fread(buffer, 1, bufferSize, fin);
      if (sizeRead < bufferSize) {
        if (feof(fin) == 0) {
          res = TRI_set_errno(TRI_ERROR_SYS_ERROR);
          break;
        }
      }

      if (sizeRead > 0) {
        res = zipWriteInFileInZip(zf, buffer, sizeRead);
        if (res != 0) {
          break;
        }
      }
      else if (sizeRead <= 0) {
        break;
      }
    }

    fclose(fin);
    
    zipCloseFileInZip(zf);

    if (res != TRI_ERROR_NO_ERROR) {
      break;
    }
  }

  zipClose(zf, NULL);
  
  TRI_Free(TRI_UNKNOWN_MEM_ZONE, buffer);

  return res;
}