Beispiel #1
0
    StatusWith<DiskLoc> RocksRecordStore::insertRecord( OperationContext* txn,
                                                        const char* data,
                                                        int len,
                                                        bool enforceQuota ) {
        if ( _isCapped && len > _cappedMaxSize ) {
            return StatusWith<DiskLoc>( ErrorCodes::BadValue,
                                       "object to insert exceeds cappedMaxSize" );
        }

        RocksRecoveryUnit* ru = _getRecoveryUnit( txn );

        DiskLoc loc = _nextId();

        ru->writeBatch()->Put( _columnFamily, _makeKey( loc ), rocksdb::Slice( data, len ) );

        _changeNumRecords( txn, true );
        _increaseDataSize( txn, len );

        cappedDeleteAsNeeded(txn);

        return StatusWith<DiskLoc>( loc );
    }
WiredTigerRecordStore::WiredTigerRecordStore(OperationContext* ctx,
                                             StringData ns,
                                             StringData uri,
                                             bool isCapped,
                                             int64_t cappedMaxSize,
                                             int64_t cappedMaxDocs,
                                             CappedDocumentDeleteCallback* cappedDeleteCallback,
                                             WiredTigerSizeStorer* sizeStorer)
    : RecordStore(ns),
      _uri(uri.toString()),
      _tableId(WiredTigerSession::genTableId()),
      _isCapped(isCapped),
      _isOplog(NamespaceString::oplog(ns)),
      _cappedMaxSize(cappedMaxSize),
      _cappedMaxSizeSlack(std::min(cappedMaxSize / 10, int64_t(16 * 1024 * 1024))),
      _cappedMaxDocs(cappedMaxDocs),
      _cappedSleep(0),
      _cappedSleepMS(0),
      _cappedDeleteCallback(cappedDeleteCallback),
      _cappedDeleteCheckCount(0),
      _useOplogHack(shouldUseOplogHack(ctx, _uri)),
      _sizeStorer(sizeStorer),
      _sizeStorerCounter(0),
      _shuttingDown(false) {
    Status versionStatus = WiredTigerUtil::checkApplicationMetadataFormatVersion(
        ctx, uri, kMinimumRecordStoreVersion, kMaximumRecordStoreVersion);
    if (!versionStatus.isOK()) {
        fassertFailedWithStatusNoTrace(28548, versionStatus);
    }

    if (_isCapped) {
        invariant(_cappedMaxSize > 0);
        invariant(_cappedMaxDocs == -1 || _cappedMaxDocs > 0);
    } else {
        invariant(_cappedMaxSize == -1);
        invariant(_cappedMaxDocs == -1);
    }

    // Find the largest RecordId currently in use and estimate the number of records.
    Cursor cursor(ctx, *this, /*forward=*/false);
    if (auto record = cursor.next()) {
        int64_t max = _makeKey(record->id);
        _oplog_highestSeen = record->id;
        _nextIdNum.store(1 + max);

        if (_sizeStorer) {
            long long numRecords;
            long long dataSize;
            _sizeStorer->loadFromCache(uri, &numRecords, &dataSize);
            _numRecords.store(numRecords);
            _dataSize.store(dataSize);
            _sizeStorer->onCreate(this, numRecords, dataSize);
        } else {
            LOG(1) << "Doing scan of collection " << ns << " to get size and count info";

            _numRecords.store(0);
            _dataSize.store(0);

            do {
                _numRecords.fetchAndAdd(1);
                _dataSize.fetchAndAdd(record->data.size());
            } while ((record = cursor.next()));
        }
    } else {
        _dataSize.store(0);
        _numRecords.store(0);
        // Need to start at 1 so we are always higher than RecordId::min()
        _nextIdNum.store(1);
        if (sizeStorer)
            _sizeStorer->onCreate(this, 0, 0);
    }

    _hasBackgroundThread = WiredTigerKVEngine::initRsOplogBackgroundThread(ns);
}
/* 
 * encrypt/decrypt using reference AES.
 */
static CSSM_RETURN encryptDecryptAES(
	CSSM_BOOL			forEncrypt,
	CSSM_ALGORITHMS		encrAlg,
	CSSM_ENCRYPT_MODE	encrMode,
	const CSSM_DATA		*iv,				//Êoptional per mode
	uint32				keySizeInBits,
	uint32				effectiveKeyBits,	// optional per key alg
	uint32				cipherBlockSize,
	uint32				rounds,				// ditto
	const CSSM_DATA		*key,				// raw key bytes
	const CSSM_DATA		*inText,
	CSSM_DATA_PTR 		outText)			// mallocd and returned
{
	keyInstance 	aesKey;
	cipherInstance 	aesCipher;
	BYTE 			mode;
	int 			artn;
	BYTE			*ivPtr;
	
	if(cipherBlockSize == 0) {
		cipherBlockSize = MIN_AES_BLOCK_BITS;
	}
	switch(encrMode) {
		case CSSM_ALGMODE_CBC_IV8:
			mode = MODE_CBC;
			ivPtr = iv->Data;
			break;
		case CSSM_ALGMODE_ECB:
			mode = MODE_ECB;
			ivPtr = NULL;
			break;
		default:
			printf("***AES reference implementation doesn't do padding (yet)\n");
			return CSSM_OK;
	}
	/* fixme - adjust for padding if necessary */
	outText->Data = (uint8 *)CSSM_MALLOC(inText->Length);
	outText->Length = inText->Length;
	artn = _makeKey(&aesKey, 
		forEncrypt ? DIR_ENCRYPT : DIR_DECRYPT,
		keySizeInBits,
		cipherBlockSize,
		key->Data);
	if(artn <= 0) {
		printf("***AES makeKey returned %d\n", artn);
		return CSSM_ERRCODE_INTERNAL_ERROR;
	}
	artn = _cipherInit(&aesCipher,
		mode,
		cipherBlockSize,
		ivPtr);
	if(artn <= 0) {
		printf("***AES cipherInit returned %d\n", artn);
		return CSSM_ERRCODE_INTERNAL_ERROR;
	}
	if(forEncrypt) {
		artn = _blockEncrypt(&aesCipher,
			&aesKey,
			(BYTE *)inText->Data,
			inText->Length * 8,
			(BYTE *)outText->Data);
	}
	else {
		artn = _blockDecrypt(&aesCipher,
			&aesKey,
			(BYTE *)inText->Data,
			inText->Length * 8,
			(BYTE *)outText->Data);
	}
	if(artn <= 0) {
		printf("***AES encrypt/decrypt returned %d\n", artn);
		return CSSM_ERRCODE_INTERNAL_ERROR;
	}
	return CSSM_OK;
}