Esempio n. 1
0
int TRI_SaveStateReplicationApplier (TRI_vocbase_t* vocbase,
                                     TRI_replication_applier_state_t const* state,
                                     bool doSync) {
  TRI_json_t* json;
  char* filename;
  int res;

  json = JsonApplyState(state);

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

  filename = GetStateFilename(vocbase);
  LOG_TRACE("saving replication applier state to file '%s'", filename);

  if (! TRI_SaveJson(filename, json, doSync)) {
    res = TRI_errno();
  }
  else {
    res = TRI_ERROR_NO_ERROR;
  }

  TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
  TRI_FreeJson(TRI_CORE_MEM_ZONE, json);

  return res;
}
Esempio n. 2
0
int TRI_SaveConfigurationReplicationApplier (TRI_vocbase_t* vocbase,
                                             TRI_replication_applier_configuration_t const* config,
                                             bool doSync) {
  TRI_json_t* json;
  char* filename;
  int res;

  json = JsonConfiguration(config, true);

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

  filename = GetConfigurationFilename(vocbase);

  if (! TRI_SaveJson(filename, json, doSync)) {
    res = TRI_errno();
  }
  else {
    res = TRI_ERROR_NO_ERROR;
  }

  TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
  TRI_FreeJson(TRI_CORE_MEM_ZONE, json);

  return res;
}
Esempio n. 3
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;
}
int TRI_SaveStateReplicationApplier (TRI_vocbase_t* vocbase,
                                     TRI_replication_applier_state_t const* state,
                                     bool doSync) {
  TRI_json_t* json;
  char* filename;
  int res;

  if (vocbase->_type == TRI_VOCBASE_TYPE_COORDINATOR) {
    return TRI_ERROR_CLUSTER_UNSUPPORTED;
  }

  json = JsonApplyState(state);

  if (json == nullptr) {
    return TRI_ERROR_OUT_OF_MEMORY;
  }

  filename = GetStateFilename(vocbase);
  LOG_TRACE("saving replication applier state to file '%s'", filename);

  if (! TRI_SaveJson(filename, json, doSync)) {
    res = TRI_errno();
  }
  else {
    res = TRI_ERROR_NO_ERROR;
  }

  TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
  TRI_FreeJson(TRI_CORE_MEM_ZONE, json);

  return res;
}
Esempio n. 5
0
int TRI_SaveCollectionInfo (char const* path, const TRI_col_info_t* const info) {
  TRI_json_t* json;
  char* filename;
  bool ok;

  filename = TRI_Concatenate2File(path, TRI_COL_PARAMETER_FILE);

  // create a json info object
  json = TRI_CreateArrayJson(TRI_UNKNOWN_MEM_ZONE);
  if (json == NULL) {
    // out of memory
    LOG_ERROR("cannot save info block '%s': out of memory", filename);

    TRI_FreeString(TRI_CORE_MEM_ZONE, filename);

    return TRI_ERROR_OUT_OF_MEMORY;
  }

  TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "version",     TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, info->_version));
  TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "type",        TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, info->_type));
  TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "cid",         TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, info->_cid));
  TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "deleted",     TRI_CreateBooleanJson(TRI_UNKNOWN_MEM_ZONE, info->_deleted));
  TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "maximalSize", TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, info->_maximalSize));
  TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "name",        TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, info->_name));
  TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "isVolatile",  TRI_CreateBooleanJson(TRI_UNKNOWN_MEM_ZONE, info->_isVolatile));
  TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "waitForSync", TRI_CreateBooleanJson(TRI_UNKNOWN_MEM_ZONE, info->_waitForSync));

  if (info->_keyOptions) {
    TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "keyOptions",     TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, info->_keyOptions));
  }

  // save json info to file
  ok = TRI_SaveJson(filename, json);
  TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);

  if (! ok) {
    LOG_ERROR("cannot save info block '%s': '%s'", filename, TRI_last_error());

    TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
    return TRI_errno();
  }

  TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
  return TRI_ERROR_NO_ERROR;
}
Esempio n. 6
0
static int UpdateLock (TRI_doc_collection_t* document,
                       TRI_shaped_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) {
  TRI_doc_mptr_t result;

  document->beginWrite(document);
  result = document->update(document, json, did, rid, oldRid, policy, true);

  if (result._did == 0) {
    return TRI_errno();
  }
  else {
    return TRI_ERROR_NO_ERROR;
  }
}
Esempio n. 7
0
static bool CheckCollection (TRI_collection_t* collection) {
  TRI_datafile_t* datafile;
  TRI_vector_pointer_t all;
  TRI_vector_pointer_t compactors;
  TRI_vector_pointer_t datafiles;
  TRI_vector_pointer_t journals;
  TRI_vector_pointer_t sealed;
  TRI_vector_string_t files;
  bool stop;
  regex_t re;
  size_t i;
  size_t n;

  stop = false;

  // check files within the directory
  files = TRI_FilesDirectory(collection->_directory);
  n = files._length;

  regcomp(&re, "^(journal|datafile|index|compactor)-([0-9][0-9]*)\\.(db|json)$", REG_EXTENDED);

  TRI_InitVectorPointer(&journals, TRI_UNKNOWN_MEM_ZONE);
  TRI_InitVectorPointer(&compactors, TRI_UNKNOWN_MEM_ZONE);
  TRI_InitVectorPointer(&datafiles, TRI_UNKNOWN_MEM_ZONE);
  TRI_InitVectorPointer(&sealed, TRI_UNKNOWN_MEM_ZONE);
  TRI_InitVectorPointer(&all, TRI_UNKNOWN_MEM_ZONE);

  for (i = 0;  i < n;  ++i) {
    char const* file = files._buffer[i];
    regmatch_t matches[4];

    if (regexec(&re, file, sizeof(matches) / sizeof(matches[0]), matches, 0) == 0) {
      char const* first = file + matches[1].rm_so;
      size_t firstLen = matches[1].rm_eo - matches[1].rm_so;

      char const* third = file + matches[3].rm_so;
      size_t thirdLen = matches[3].rm_eo - matches[3].rm_so;

      // .............................................................................
      // file is an index, just store the filename
      // .............................................................................

      if (TRI_EqualString2("index", first, firstLen) && TRI_EqualString2("json", third, thirdLen)) {
        char* filename;

        filename = TRI_Concatenate2File(collection->_directory, file);
        TRI_PushBackVectorString(&collection->_indexFiles, filename);
      }

      // .............................................................................
      // file is a journal or datafile, open the datafile
      // .............................................................................

      else if (TRI_EqualString2("db", third, thirdLen)) {
        char* filename;
        char* ptr;
        TRI_col_header_marker_t* cm;

        filename = TRI_Concatenate2File(collection->_directory, file);
        datafile = TRI_OpenDatafile(filename);

        if (datafile == NULL) {
          collection->_lastError = TRI_errno();
          stop = true;

          LOG_ERROR("cannot open datafile '%s': %s", filename, TRI_last_error());

          break;
        }

        TRI_PushBackVectorPointer(&all, datafile);

        // check the document header
        ptr  = datafile->_data;
        ptr += TRI_DF_ALIGN_BLOCK(sizeof(TRI_df_header_marker_t));
        cm   = (TRI_col_header_marker_t*) ptr;

        if (cm->base._type != TRI_COL_MARKER_HEADER) {
          LOG_ERROR("collection header mismatch in file '%s', expected TRI_COL_MARKER_HEADER, found %lu",
                    filename,
                    (unsigned long) cm->base._type);

          TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
          stop = true;
          break;
        }

        if (cm->_cid != collection->_info._cid) {
          LOG_ERROR("collection identifier mismatch, expected %llu, found %llu",
                    (unsigned long long) collection->_info._cid,
                    (unsigned long long) cm->_cid);

          TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
          stop = true;
          break;
        }

        // file is a journal
        if (TRI_EqualString2("journal", first, firstLen)) {
          if (datafile->_isSealed) {
            LOG_WARNING("strange, journal '%s' is already sealed; must be a left over; will use it as datafile", filename);

            TRI_PushBackVectorPointer(&sealed, datafile);
          }
          else {
            TRI_PushBackVectorPointer(&journals, datafile);
          }
        }

        // file is a compactor file
        else if (TRI_EqualString2("compactor", first, firstLen)) {
          if (datafile->_isSealed) {
            LOG_WARNING("strange, compactor journal '%s' is already sealed; must be a left over; will use it as datafile", filename);

            TRI_PushBackVectorPointer(&sealed, datafile);
          }
          else {
            TRI_PushBackVectorPointer(&compactors, datafile);
          }
        }

        // file is a datafile
        else if (TRI_EqualString2("datafile", first, firstLen)) {
          if (! datafile->_isSealed) {
            LOG_ERROR("datafile '%s' is not sealed, this should never happen", filename);
            collection->_lastError = TRI_set_errno(TRI_ERROR_ARANGO_CORRUPTED_DATAFILE);
            stop = true;
            break;
          }
          else {
            TRI_PushBackVectorPointer(&datafiles, datafile);
          }
        }
        else {
          LOG_ERROR("unknown datafile '%s'", file);
        }

        TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
      }
      else {
        LOG_ERROR("unknown datafile '%s'", file);
      }
    }
  }

  TRI_DestroyVectorString(&files);

  regfree(&re);

  // convert the sealed journals into datafiles
  if (! stop) {
    n = sealed._length;

    for (i = 0;  i < n;  ++i) {
      char* number;
      char* dname;
      char* filename;
      bool ok;

      datafile = sealed._buffer[i];

      number = TRI_StringUInt64(datafile->_fid);
      dname = TRI_Concatenate3String("datafile-", number, ".db");
      filename = TRI_Concatenate2File(collection->_directory, dname);

      TRI_FreeString(TRI_CORE_MEM_ZONE, dname);
      TRI_FreeString(TRI_CORE_MEM_ZONE, number);

      ok = TRI_RenameDatafile(datafile, filename);

      if (ok) {
        TRI_PushBackVectorPointer(&datafiles, datafile);
        LOG_DEBUG("renamed sealed journal to '%s'", filename);
      }
      else {
        collection->_lastError = datafile->_lastError;
        stop = true;
        LOG_ERROR("cannot rename sealed log-file to %s, this should not happen: %s", filename, TRI_last_error());
        break;
      }

      TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
    }
  }

  TRI_DestroyVectorPointer(&sealed);

  // stop if necessary
  if (stop) {
    n = all._length;

    for (i = 0;  i < n;  ++i) {
      datafile = all._buffer[i];

      LOG_TRACE("closing datafile '%s'", datafile->_filename);

      TRI_CloseDatafile(datafile);
      TRI_FreeDatafile(datafile);
    }

    TRI_DestroyVectorPointer(&all);
    TRI_DestroyVectorPointer(&datafiles);

    return false;
  }

  TRI_DestroyVectorPointer(&all);

  // add the datafiles and journals
  collection->_datafiles = datafiles;
  collection->_journals = journals;
  collection->_compactors = compactors;

  return true;
}
Esempio n. 8
0
static TRI_datafile_t* CreateJournal (TRI_primary_collection_t* primary, bool compactor) {
  TRI_col_header_marker_t cm;
  TRI_collection_t* collection;
  TRI_datafile_t* journal;
  TRI_df_marker_t* position;
  int res;
  char* filename;

  collection = &primary->base;

  if (collection->_info._isVolatile) {
    // in-memory collection
    filename = NULL;
  }
  else {
    char* jname;
    char* number;

    // construct a suitable filename
    number = TRI_StringUInt64(TRI_NewTickVocBase());

    if (compactor) {
      jname = TRI_Concatenate3String("journal-", number, ".db");
    }
    else {
      jname = TRI_Concatenate3String("compactor-", number, ".db");
    }

    filename = TRI_Concatenate2File(collection->_directory, jname);

    TRI_FreeString(TRI_CORE_MEM_ZONE, number);
    TRI_FreeString(TRI_CORE_MEM_ZONE, jname);
  }

  // create journal file
  journal = TRI_CreateDatafile(filename, collection->_info._maximalSize);

  if (filename != NULL) {
    TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
  }

  if (journal == NULL) {
    if (TRI_errno() == TRI_ERROR_OUT_OF_MEMORY_MMAP) {
      collection->_lastError = TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY_MMAP);
      collection->_state = TRI_COL_STATE_READ;
    }
    else {
      collection->_lastError = TRI_set_errno(TRI_ERROR_ARANGO_NO_JOURNAL);
      collection->_state = TRI_COL_STATE_WRITE_ERROR;
    }

    return NULL;
  }

  LOG_TRACE("created a new primary journal '%s'", journal->getName(journal));


  if (journal->isPhysical(journal)) {
    char* jname;
    char* number;
    bool ok;

    // and use the correct name
    number = TRI_StringUInt64(journal->_fid);

    if (compactor) {
      jname = TRI_Concatenate3String("compactor-", number, ".db");
    }
    else {
      jname = TRI_Concatenate3String("journal-", number, ".db");
    }

    filename = TRI_Concatenate2File(collection->_directory, jname);

    TRI_FreeString(TRI_CORE_MEM_ZONE, number);
    TRI_FreeString(TRI_CORE_MEM_ZONE, jname);

    ok = TRI_RenameDatafile(journal, filename);

    if (! ok) {
      LOG_WARNING("failed to rename the journal to '%s': %s", filename, TRI_last_error());
    }
    else {
      LOG_TRACE("renamed journal to '%s'", filename);
    }

    TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
  }


  // create a collection header
  res = TRI_ReserveElementDatafile(journal, sizeof(TRI_col_header_marker_t), &position);

  if (res != TRI_ERROR_NO_ERROR) {
    collection->_lastError = journal->_lastError;
    LOG_ERROR("cannot create document header in journal '%s': %s", journal->getName(journal), TRI_last_error());

    TRI_FreeDatafile(journal);

    return NULL;
  }

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

  cm.base._size = sizeof(TRI_col_header_marker_t);
  cm.base._type = TRI_COL_MARKER_HEADER;
  cm.base._tick = TRI_NewTickVocBase();

  cm._cid = collection->_info._cid;

  TRI_FillCrcMarkerDatafile(journal, &cm.base, sizeof(cm), 0, 0, 0, 0);

  res = TRI_WriteElementDatafile(journal, position, &cm.base, sizeof(cm), 0, 0, 0, 0, true);

  if (res != TRI_ERROR_NO_ERROR) {
    collection->_lastError = journal->_lastError;
    LOG_ERROR("cannot create document header in journal '%s': %s", journal->getName(journal), TRI_last_error());

    TRI_FreeDatafile(journal);

    return NULL;
  }

  // that's it
  if (compactor) {
    TRI_PushBackVectorPointer(&collection->_compactors, journal);
  }
  else {
    TRI_PushBackVectorPointer(&collection->_journals, journal);
  }

  return journal;
}
static TRI_datafile_t* CreateJournal (TRI_primary_collection_t* primary, 
                                      TRI_voc_size_t maximalSize) {
  TRI_col_header_marker_t cm;
  TRI_collection_t* collection;
  TRI_datafile_t* journal;
  TRI_df_marker_t* position;
  TRI_voc_fid_t fid;
  int res;

  collection = &primary->base;

  fid = (TRI_voc_fid_t) TRI_NewTickServer();

  if (collection->_info._isVolatile) {
    // in-memory collection
    journal = TRI_CreateDatafile(NULL, fid, maximalSize);
  }
  else {
    char* jname;
    char* number;
    char* filename;

    // construct a suitable filename (which is temporary at the beginning)
    number   = TRI_StringUInt64(fid);
    jname    = TRI_Concatenate3String("temp-", number, ".db");
    filename = TRI_Concatenate2File(collection->_directory, jname);

    TRI_FreeString(TRI_CORE_MEM_ZONE, number);
    TRI_FreeString(TRI_CORE_MEM_ZONE, jname);

    journal = TRI_CreateDatafile(filename, fid, maximalSize);
    TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
  }

  if (journal == NULL) {
    if (TRI_errno() == TRI_ERROR_OUT_OF_MEMORY_MMAP) {
      collection->_lastError = TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY_MMAP);
      collection->_state = TRI_COL_STATE_READ;
    }
    else {
      collection->_lastError = TRI_set_errno(TRI_ERROR_ARANGO_NO_JOURNAL);
      collection->_state = TRI_COL_STATE_WRITE_ERROR;
    }

    return NULL;
  }

  LOG_TRACE("created new journal '%s'", journal->getName(journal));


  // create a collection header, still in the temporary file
  res = TRI_ReserveElementDatafile(journal, sizeof(TRI_col_header_marker_t), &position, maximalSize);

  if (res != TRI_ERROR_NO_ERROR) {
    collection->_lastError = journal->_lastError;
    LOG_ERROR("cannot create document header in journal '%s': %s", journal->getName(journal), TRI_last_error());

    TRI_FreeDatafile(journal);

    return NULL;
  }


  TRI_InitMarker((char*) &cm, TRI_COL_MARKER_HEADER, sizeof(TRI_col_header_marker_t));
  cm.base._tick = (TRI_voc_tick_t) fid;
  cm._type = (TRI_col_type_t) collection->_info._type;
  cm._cid  = collection->_info._cid;

  res = TRI_WriteCrcElementDatafile(journal, position, &cm.base, sizeof(cm), true);

  if (res != TRI_ERROR_NO_ERROR) {
    collection->_lastError = journal->_lastError;
    LOG_ERROR("cannot create document header in journal '%s': %s", journal->getName(journal), TRI_last_error());

    TRI_FreeDatafile(journal);

    return NULL;
  }

  assert(fid == journal->_fid);


  // if a physical file, we can rename it from the temporary name to the correct name
  if (journal->isPhysical(journal)) {
    char* jname;
    char* number;
    char* filename;
    bool ok;

    // and use the correct name
    number = TRI_StringUInt64(journal->_fid);
    jname = TRI_Concatenate3String("journal-", number, ".db");

    filename = TRI_Concatenate2File(collection->_directory, jname);

    TRI_FreeString(TRI_CORE_MEM_ZONE, number);
    TRI_FreeString(TRI_CORE_MEM_ZONE, jname);

    ok = TRI_RenameDatafile(journal, filename);

    if (! ok) {
      LOG_ERROR("failed to rename the journal to '%s': %s", filename, TRI_last_error());
      TRI_FreeDatafile(journal);
      TRI_FreeString(TRI_CORE_MEM_ZONE, filename);

      return NULL;
    }
    else {
      LOG_TRACE("renamed journal from %s to '%s'", journal->getName(journal), filename);
    }

    TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
  }

  TRI_PushBackVectorPointer(&collection->_journals, journal);

  return journal;
}
Esempio n. 10
0
static TRI_datafile_t* CreateCompactor (TRI_primary_collection_t* primary, 
                                        TRI_voc_fid_t fid,
                                        TRI_voc_size_t maximalSize) {
  TRI_col_header_marker_t cm;
  TRI_collection_t* collection;
  TRI_datafile_t* journal;
  TRI_df_marker_t* position;
  int res;

  collection = &primary->base;

  if (collection->_info._isVolatile) {
    // in-memory collection
    journal = TRI_CreateDatafile(NULL, fid, maximalSize);
  }
  else {
    char* jname;
    char* number;
    char* filename;

    number   = TRI_StringUInt64(fid);
    jname    = TRI_Concatenate3String("compaction-", number, ".db");
    filename = TRI_Concatenate2File(collection->_directory, jname);

    TRI_FreeString(TRI_CORE_MEM_ZONE, number);
    TRI_FreeString(TRI_CORE_MEM_ZONE, jname);

    if (TRI_ExistsFile(filename)) {
      // remove any existing temporary file first
      TRI_UnlinkFile(filename);
    }

    journal = TRI_CreateDatafile(filename, fid, maximalSize);
    TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
  }

  if (journal == NULL) {
    if (TRI_errno() == TRI_ERROR_OUT_OF_MEMORY_MMAP) {
      collection->_lastError = TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY_MMAP);
      collection->_state = TRI_COL_STATE_READ;
    }
    else {
      collection->_lastError = TRI_set_errno(TRI_ERROR_ARANGO_NO_JOURNAL);
      collection->_state = TRI_COL_STATE_WRITE_ERROR;
    }

    return NULL;
  }

  LOG_TRACE("created new compactor '%s'", journal->getName(journal));


  // create a collection header, still in the temporary file
  res = TRI_ReserveElementDatafile(journal, sizeof(TRI_col_header_marker_t), &position, maximalSize);

  if (res != TRI_ERROR_NO_ERROR) {
    collection->_lastError = journal->_lastError;
    LOG_ERROR("cannot create document header in compactor '%s': %s", journal->getName(journal), TRI_last_error());

    TRI_FreeDatafile(journal);

    return NULL;
  }


  TRI_InitMarker((char*) &cm, TRI_COL_MARKER_HEADER, sizeof(TRI_col_header_marker_t));
  cm.base._tick = (TRI_voc_tick_t) fid;
  cm._type = (TRI_col_type_t) collection->_info._type;
  cm._cid  = collection->_info._cid;

  res = TRI_WriteCrcElementDatafile(journal, position, &cm.base, sizeof(cm), false);

  if (res != TRI_ERROR_NO_ERROR) {
    collection->_lastError = journal->_lastError;
    LOG_ERROR("cannot create document header in compactor '%s': %s", journal->getName(journal), TRI_last_error());

    TRI_FreeDatafile(journal);

    return NULL;
  }

  assert(fid == journal->_fid);

  return journal;
}
Esempio n. 11
0
static bool CreateJournal (TRI_shape_collection_t* collection) {
  TRI_col_header_marker_t cm;
  TRI_datafile_t* journal;
  TRI_df_marker_t* position;
  char* filename;
  int res;

  if (collection->base._info._isVolatile) {
    // in memory collection
    filename = NULL;
  }
  else {
    char* jname;
    char* number;

    number = TRI_StringUInt32(TRI_NewTickVocBase());
    if (! number) {
      return false;
    }
  
    jname = TRI_Concatenate3String("journal-", number, ".db");
    TRI_FreeString(TRI_CORE_MEM_ZONE, number);

    filename = TRI_Concatenate2File(collection->base._directory, jname);
    TRI_FreeString(TRI_CORE_MEM_ZONE, jname);
  }

  journal = TRI_CreateDatafile(filename, collection->base._info._maximalSize);
  
  if (filename != NULL) {
    TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
  }

  // check that a journal was created
  if (journal == NULL) {
    if (TRI_errno() == TRI_ERROR_OUT_OF_MEMORY_MMAP) {
      collection->base._lastError = TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY_MMAP);
      collection->base._state = TRI_COL_STATE_READ;
    }
    else {
      collection->base._lastError = TRI_set_errno(TRI_ERROR_ARANGO_NO_JOURNAL);
      collection->base._state = TRI_COL_STATE_WRITE_ERROR;
    }

    return false;
  }

  LOG_TRACE("created a new shape journal '%s'", journal->getName(journal));


  if (journal->isPhysical(journal)) {
    char* jname;
    char* number;
    bool ok;

    // and use the correct name
    number = TRI_StringUInt32(journal->_fid);
    jname = TRI_Concatenate3String("journal-", number, ".db");
    filename = TRI_Concatenate2File(collection->base._directory, jname);

    TRI_FreeString(TRI_CORE_MEM_ZONE, number);
    TRI_FreeString(TRI_CORE_MEM_ZONE, jname);

    ok = TRI_RenameDatafile(journal, filename);

    if (! ok) {
      // TODO: remove disastrous call to exit() here
      LOG_FATAL_AND_EXIT("failed to rename the journal to '%s': %s", filename, TRI_last_error());
    }
    else {
      LOG_TRACE("renamed journal to '%s'", filename);
    }

    TRI_FreeString(TRI_CORE_MEM_ZONE, filename);
  }


  // create a collection header
  res = TRI_ReserveElementDatafile(journal, sizeof(TRI_col_header_marker_t), &position);

  if (res != TRI_ERROR_NO_ERROR) {
    LOG_ERROR("cannot create document header in journal '%s': %s",
              journal->getName(journal),
              TRI_last_error());
    
    TRI_FreeDatafile(journal);

    return false;
  }

  // create a header
  memset(&cm, 0, sizeof(cm));

  cm.base._size = sizeof(TRI_col_header_marker_t);
  cm.base._type = TRI_COL_MARKER_HEADER;
  cm.base._tick = TRI_NewTickVocBase();

  cm._cid = collection->base._info._cid;

  TRI_FillCrcMarkerDatafile(journal, &cm.base, sizeof(cm), 0, 0, 0, 0);

  // on journal creation, always use waitForSync = true
  res = TRI_WriteElementDatafile(journal, position, &cm.base, sizeof(cm), 0, 0, 0, 0, true);

  if (res != TRI_ERROR_NO_ERROR) {
    LOG_ERROR("cannot create document header in journal '%s': %s",
              journal->getName(journal),
              TRI_last_error());
    
    TRI_FreeDatafile(journal);

    return false;
  }

  // that's it
  TRI_PushBackVectorPointer(&collection->base._journals, journal);
  return true;
}