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 }
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) }
// 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 }
// 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() }
// 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 }
// 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 }