Exemplo n.º 1
0
void TRI_RemoveBarrierCollectionsAql (TRI_aql_context_t* const context) {
  size_t i;

  // iterate in reverse order
  i = context->_collections._length;
  while (i--) {
    TRI_aql_collection_t* collection = (TRI_aql_collection_t*) context->_collections._buffer[i];

    assert(collection);
    assert(collection->_name);

    if (! collection->_collection || ! collection->_barrier) {
      // don't process collections we weren't able to lock at all
      continue;
    }

    assert(collection->_barrier);
    assert(collection->_collection->_collection);

    LOG_TRACE("removing barrier for collection '%s'", collection->_name);

    TRI_FreeBarrier(collection->_barrier);
    collection->_barrier = NULL;
  }
}
Exemplo n.º 2
0
void TRI_CompactorVocBase (void* data) {
  TRI_vocbase_t* vocbase;
  TRI_vector_pointer_t collections;

  vocbase = data;
  assert(vocbase->_state == 1);

  TRI_InitVectorPointer(&collections, TRI_UNKNOWN_MEM_ZONE);

  while (true) {
    int state;
    
    // keep initial _state value as vocbase->_state might change during compaction loop
    state = vocbase->_state;
      
    // check if compaction is currently disallowed
    if (CheckAndLockCompaction(vocbase)) {
      // compaction is currently allowed
      size_t i, n;

      // copy all collections
      TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase);
      TRI_CopyDataVectorPointer(&collections, &vocbase->_collections);
      TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);

      n = collections._length;

      for (i = 0;  i < n;  ++i) {
        TRI_vocbase_col_t* collection;
        TRI_primary_collection_t* primary;
        TRI_col_type_e type;
        bool doCompact;
        bool worked;
      
        collection = collections._buffer[i];

        if (! TRI_TRY_READ_LOCK_STATUS_VOCBASE_COL(collection)) {
          // if we can't acquire the read lock instantly, we continue directly
          // we don't want to stall here for too long
          continue;
        }

        primary = collection->_collection;

        if (primary == NULL) {
          TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
          continue;
        }

        worked    = false;
        doCompact = primary->base._info._doCompact;
        type      = primary->base._info._type;

        // for document collection, compactify datafiles
        if (TRI_IS_DOCUMENT_COLLECTION(type)) {
          if (collection->_status == TRI_VOC_COL_STATUS_LOADED && doCompact) {
            TRI_barrier_t* ce;
            
            // check whether someone else holds a read-lock on the compaction lock
            if (! TRI_TryWriteLockReadWriteLock(&primary->_compactionLock)) {
              // someone else is holding the compactor lock, we'll not compact
              TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
              continue;
            }

            ce = TRI_CreateBarrierCompaction(&primary->_barrierList);

            if (ce == NULL) {
              // out of memory
              LOG_WARNING("out of memory when trying to create a barrier element");
            }
            else {
              worked = CompactifyDocumentCollection((TRI_document_collection_t*) primary);

              TRI_FreeBarrier(ce);
            }
          
            // read-unlock the compaction lock
            TRI_WriteUnlockReadWriteLock(&primary->_compactionLock);
          }
        }

        TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);

        if (worked) {
          // signal the cleanup thread that we worked and that it can now wake up
          TRI_LockCondition(&vocbase->_cleanupCondition);
          TRI_SignalCondition(&vocbase->_cleanupCondition);
          TRI_UnlockCondition(&vocbase->_cleanupCondition);
        }
      }

      UnlockCompaction(vocbase);
    }


    if (state != 2 && vocbase->_state == 1) {
      // only sleep while server is still running
      TRI_LockCondition(&vocbase->_compactorCondition);
      TRI_TimedWaitCondition(&vocbase->_compactorCondition, (uint64_t) COMPACTOR_INTERVAL);
      TRI_UnlockCondition(&vocbase->_compactorCondition);
    }

    if (state == 2) {
      // server shutdown
      break;
    }
  }

  TRI_DestroyVectorPointer(&collections);

  LOG_TRACE("shutting down compactor thread");
}