예제 #1
0
func fetchDataNodesFromDBFor(bucketKey *bucketKey) (dataNodes, error) {
	logger.Debug("Fetching from DB data nodes for bucket [%s]", bucketKey)
	openchainDB := db.GetDBHandle()
	itr := openchainDB.GetStateCFIterator()
	defer itr.Close()
	minimumDataKeyBytes := minimumPossibleDataKeyBytesFor(bucketKey)

	var dataNodes dataNodes

	itr.Seek(minimumDataKeyBytes)

	for ; itr.Valid(); itr.Next() {

		// making a copy of key-value bytes because, underlying key bytes are reused by itr.
		// no need to free slices as iterator frees memory when closed.
		keyBytes := statemgmt.Copy(itr.Key().Data())
		valueBytes := statemgmt.Copy(itr.Value().Data())

		dataKey := newDataKeyFromEncodedBytes(keyBytes)
		logger.Debug("Retrieved data key [%s] from DB for bucket [%s]", dataKey, bucketKey)
		if !dataKey.getBucketKey().equals(bucketKey) {
			logger.Debug("Data key [%s] from DB does not belong to bucket = [%s]. Stopping further iteration and returning results [%v]", dataKey, bucketKey, dataNodes)
			return dataNodes, nil
		}
		dataNode := unmarshalDataNode(dataKey, valueBytes)

		logger.Debug("Data node [%s] from DB belongs to bucket = [%s]. Including the key in results...", dataNode, bucketKey)
		dataNodes = append(dataNodes, dataNode)
	}
	logger.Debug("Returning results [%v]", dataNodes)
	return dataNodes, nil
}
예제 #2
0
func (cache *bucketCache) loadAllBucketNodesFromDB() {
	if !cache.isEnabled {
		return
	}
	openchainDB := db.GetDBHandle()
	itr := openchainDB.GetStateCFIterator()
	defer itr.Close()
	itr.Seek([]byte{byte(0)})
	count := 0
	cache.lock.Lock()
	defer cache.lock.Unlock()
	for ; itr.Valid(); itr.Next() {
		key := itr.Key().Data()
		if key[0] != byte(0) {
			itr.Key().Free()
			itr.Value().Free()
			break
		}
		bKey := decodeBucketKey(statemgmt.Copy(itr.Key().Data()))
		nodeBytes := statemgmt.Copy(itr.Value().Data())
		bucketNode := unmarshalBucketNode(&bKey, nodeBytes)
		size := bKey.size() + bucketNode.size()
		cache.size += size
		if cache.size >= cache.maxSize {
			cache.size -= size
			break
		}
		cache.c[bKey] = bucketNode
		itr.Key().Free()
		itr.Value().Free()
		count++
	}
	logger.Info("Loaded buckets data in cache. Total buckets in DB = [%d]. Total cache size:=%d", count, cache.size)
}
예제 #3
0
// Next - see interface 'statemgmt.RangeScanIterator' for details
func (itr *RangeScanIterator) Next() bool {
	if itr.done {
		return false
	}
	for ; itr.dbItr.Valid(); itr.dbItr.Next() {

		// making a copy of key-value bytes because, underlying key bytes are reused by itr.
		// no need to free slices as iterator frees memory when closed.
		trieKeyBytes := statemgmt.Copy(itr.dbItr.Key().Data())
		trieNodeBytes := statemgmt.Copy(itr.dbItr.Value().Data())
		value := unmarshalTrieNodeValue(trieNodeBytes)
		if value == nil {
			continue
		}

		// found an actual key
		currentCompositeKey := trieKeyEncoderImpl.decodeTrieKeyBytes(statemgmt.Copy(trieKeyBytes))
		currentChaincodeID, currentKey := statemgmt.DecodeCompositeKey(currentCompositeKey)
		if currentChaincodeID == itr.chaincodeID && (itr.endKey == "" || currentKey <= itr.endKey) {
			itr.currentKey = currentKey
			itr.currentValue = value
			itr.dbItr.Next()
			return true
		}

		// retrieved all the keys in the given range
		break
	}
	itr.done = true
	return false
}
예제 #4
0
// GetRawKeyValue - see interface 'statemgmt.StateSnapshotIterator' for details
func (snapshotItr *StateSnapshotIterator) GetRawKeyValue() ([]byte, []byte) {

	// making a copy of key-value bytes because, underlying key bytes are reused by itr.
	// no need to free slices as iterator frees memory when closed.
	keyBytes := statemgmt.Copy(snapshotItr.dbItr.Key().Data())
	valueBytes := statemgmt.Copy(snapshotItr.dbItr.Value().Data())
	dataNode := unmarshalDataNodeFromBytes(keyBytes, valueBytes)
	return dataNode.getCompositeKey(), dataNode.getValue()
}
예제 #5
0
// Next - see interface 'statemgmt.StateSnapshotIterator' for details
func (snapshotItr *StateSnapshotIterator) Next() bool {
	var available bool
	for ; snapshotItr.dbItr.Valid(); snapshotItr.dbItr.Next() {

		// making a copy of key-value bytes because, underlying key bytes are reused by itr.
		// no need to free slices as iterator frees memory when closed.
		trieKeyBytes := statemgmt.Copy(snapshotItr.dbItr.Key().Data())
		trieNodeBytes := statemgmt.Copy(snapshotItr.dbItr.Value().Data())
		value := unmarshalTrieNodeValue(trieNodeBytes)
		if util.NotNil(value) {
			snapshotItr.currentKey = trieKeyEncoderImpl.decodeTrieKeyBytes(statemgmt.Copy(trieKeyBytes))
			snapshotItr.currentValue = value
			available = true
			snapshotItr.dbItr.Next()
			break
		}
	}
	return available
}
예제 #6
0
// Next - see interface 'statemgmt.RangeScanIterator' for details
func (itr *RangeScanIterator) Next() bool {
	if itr.done {
		return false
	}

	for itr.dbItr.Valid() {

		// making a copy of key-value bytes because, underlying key bytes are reused by itr.
		// no need to free slices as iterator frees memory when closed.
		keyBytes := statemgmt.Copy(itr.dbItr.Key().Data())
		valueBytes := statemgmt.Copy(itr.dbItr.Value().Data())

		dataNode := unmarshalDataNodeFromBytes(keyBytes, valueBytes)
		dataKey := dataNode.dataKey
		chaincodeID, key := statemgmt.DecodeCompositeKey(dataNode.getCompositeKey())
		value := dataNode.value
		logger.Debug("Evaluating data-key = %s", dataKey)

		bucketNumber := dataKey.bucketKey.bucketNumber
		if bucketNumber > itr.currentBucketNumber {
			itr.seekForStartKeyWithinBucket(bucketNumber)
			continue
		}

		if chaincodeID == itr.chaincodeID && (itr.endKey == "" || key <= itr.endKey) {
			logger.Debug("including data-key = %s", dataKey)
			itr.currentKey = key
			itr.currentValue = value
			itr.dbItr.Next()
			return true
		}

		itr.seekForStartKeyWithinBucket(bucketNumber + 1)
		continue
	}
	itr.done = true
	return false
}