github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/ledger/kvledger/txmgmt/queryutil/query_executer_combiner.go (about)

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package queryutil
     8  
     9  import (
    10  	"github.com/hechain20/hechain/common/flogging"
    11  	commonledger "github.com/hechain20/hechain/common/ledger"
    12  	"github.com/hechain20/hechain/core/ledger/kvledger/txmgmt/privacyenabledstate"
    13  	"github.com/hechain20/hechain/core/ledger/kvledger/txmgmt/statedb"
    14  	"github.com/hechain20/hechain/core/ledger/util"
    15  )
    16  
    17  var logger = flogging.MustGetLogger("util")
    18  
    19  //go:generate counterfeiter -o mock/query_executer.go -fake-name QueryExecuter . QueryExecuter
    20  
    21  // QueryExecuter encapsulates query functions
    22  type QueryExecuter interface {
    23  	GetState(namespace, key string) (*statedb.VersionedValue, error)
    24  	GetStateRangeScanIterator(namespace, startKey, endKey string) (statedb.ResultsIterator, error)
    25  	GetPrivateDataHash(namespace, collection, key string) (*statedb.VersionedValue, error)
    26  }
    27  
    28  // QECombiner combines the query results from one or more underlying 'QueryExecuters'
    29  // In case, the same key is returned by multiple 'QueryExecuters', the first 'QueryExecuter'
    30  // in the input is considered having the latest state of the key
    31  type QECombiner struct {
    32  	QueryExecuters []QueryExecuter // actual executers in decending order of priority
    33  }
    34  
    35  // GetState returns the value of the key from first QueryExecuter in the slice that contains the state of the key
    36  func (c *QECombiner) GetState(namespace string, key string) ([]byte, error) {
    37  	var vv *statedb.VersionedValue
    38  	var val []byte
    39  	var err error
    40  	for _, qe := range c.QueryExecuters {
    41  		if vv, err = qe.GetState(namespace, key); err != nil {
    42  			return nil, err
    43  		}
    44  		if vv != nil {
    45  			if !vv.IsDelete() {
    46  				val = vv.Value
    47  			}
    48  			break
    49  		}
    50  	}
    51  	return val, nil
    52  }
    53  
    54  // GetStateRangeScanIterator returns an iterator that can be used to iterate over the range between startKey(inclusive) and
    55  // endKey (exclusive). The results retuned are unioin of the results returned by the individual QueryExecuters in the global
    56  // sort order of the key
    57  func (c *QECombiner) GetStateRangeScanIterator(namespace string, startKey string, endKey string) (commonledger.ResultsIterator, error) {
    58  	var itrs []statedb.ResultsIterator
    59  	for _, qe := range c.QueryExecuters {
    60  		itr, err := qe.GetStateRangeScanIterator(namespace, startKey, endKey)
    61  		if err != nil {
    62  			for _, itr := range itrs {
    63  				itr.Close()
    64  			}
    65  			return nil, err
    66  		}
    67  		itrs = append(itrs, itr)
    68  	}
    69  	itrCombiner, err := newItrCombiner(namespace, itrs)
    70  	if err != nil {
    71  		return nil, err
    72  	}
    73  	return itrCombiner, nil
    74  }
    75  
    76  // GetPrivateDataHash returns the hashed value of a private data key from first QueryExecuter in the slice
    77  // that contains the state of the hash of the key
    78  func (c *QECombiner) GetPrivateDataHash(namespace, collection, key string) ([]byte, error) {
    79  	var vv *statedb.VersionedValue
    80  	var val []byte
    81  	var err error
    82  	for _, qe := range c.QueryExecuters {
    83  		vv, err = qe.GetPrivateDataHash(namespace, collection, key)
    84  		if err != nil {
    85  			return nil, err
    86  		}
    87  		if vv != nil {
    88  			if !vv.IsDelete() {
    89  				val = vv.Value
    90  			}
    91  			break
    92  		}
    93  	}
    94  	return val, nil
    95  }
    96  
    97  // UpdateBatchBackedQueryExecuter wraps an update batch for providing functions in the interface QueryExecuter
    98  type UpdateBatchBackedQueryExecuter struct {
    99  	UpdateBatch      *statedb.UpdateBatch
   100  	HashUpdatesBatch *privacyenabledstate.HashedUpdateBatch
   101  }
   102  
   103  // GetState return the state of the in the UpdateBatch
   104  func (qe *UpdateBatchBackedQueryExecuter) GetState(ns, key string) (*statedb.VersionedValue, error) {
   105  	return qe.UpdateBatch.Get(ns, key), nil
   106  }
   107  
   108  // GetStateRangeScanIterator returns an iterator to scan over the range of the keys present in the UpdateBatch
   109  func (qe *UpdateBatchBackedQueryExecuter) GetStateRangeScanIterator(namespace, startKey, endKey string) (statedb.ResultsIterator, error) {
   110  	return qe.UpdateBatch.GetRangeScanIterator(namespace, startKey, endKey), nil
   111  }
   112  
   113  // GetPrivateDataHash returns the hashed value assosicited with a private data key from the UpdateBatch
   114  func (qe *UpdateBatchBackedQueryExecuter) GetPrivateDataHash(ns, coll, key string) (*statedb.VersionedValue, error) {
   115  	keyHash := util.ComputeStringHash(key)
   116  	return qe.HashUpdatesBatch.Get(ns, coll, string(keyHash)), nil
   117  }