NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

aggregators.py (4653B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\dbuff\common\aggregators.py
      2 from __future__ import print_function
      3 import dbuff.storage
      4 
      5 class Aggregator(object):
      6     __slots__ = ['_sortedInputs', '_continuousInput']
      7 
      8     def __init__(self, expiryTime, outputValue):
      9         if expiryTime is None:
     10             self._continuousInput = outputValue
     11             self._sortedInputs = []
     12         else:
     13             self._continuousInput = None
     14             self._sortedInputs = [(expiryTime, outputValue)]
     15 
     16     def HasInputs(self):
     17         return len(self._sortedInputs) > 0 or self._continuousInput is not None
     18 
     19     def GetNextExpiryTime(self):
     20         if self._sortedInputs:
     21             return self._sortedInputs[0][0]
     22         if self._continuousInput is None:
     23             return 0
     24 
     25     def GetFinalExpiryTime(self):
     26         if self._continuousInput is not None:
     27             return
     28         if self._sortedInputs:
     29             return self._sortedInputs[-1][0]
     30 
     31     def GetCurrentOutputValue(self):
     32         if self._sortedInputs and self._continuousInput is not None:
     33             return self._PickValue(self._continuousInput, self._sortedInputs[0][1])
     34         if self._continuousInput is not None:
     35             return self._continuousInput
     36         if self._sortedInputs:
     37             return self._sortedInputs[0][1]
     38 
     39     def _PickValue(self, *values):
     40         raise NotImplementedError()
     41 
     42     def MergeNewTimedInput(self, newExpiryTime, newValue):
     43         raise NotImplementedError()
     44 
     45     def SetContinuousInput(self, newValue):
     46         if self._continuousInput is None:
     47             self._continuousInput = newValue
     48         else:
     49             self._continuousInput = self._PickValue(self._continuousInput, newValue)
     50 
     51     def ClearContinuousInput(self):
     52         self._continuousInput = None
     53 
     54     def DiscardExpiredTimedInputs(self, now):
     55         while self._sortedInputs and self._sortedInputs[0][0] < now:
     56             self._sortedInputs.pop(0)
     57 
     58     def GetStateForClient(self):
     59         return (self.GetCurrentOutputValue(), self.GetFinalExpiryTime())
     60 
     61 
     62 class AggregatorMinimum(Aggregator):
     63     __slots__ = []
     64 
     65     def MergeNewTimedInput(self, newExpiryTime, newValue):
     66         for expiryTime, value in self._sortedInputs:
     67             if expiryTime >= newExpiryTime and value <= newValue:
     68                 return
     69 
     70         result = [ (expiryTime, value) for expiryTime, value in self._sortedInputs if expiryTime < newExpiryTime and value < newValue ]
     71         result.append((newExpiryTime, newValue))
     72         result.extend([ (expiryTime, value) for expiryTime, value in self._sortedInputs if expiryTime > newExpiryTime and value > newValue ])
     73         self._sortedInputs = result
     74 
     75     def _PickValue(self, *values):
     76         return min(values)
     77 
     78 
     79 class AggregatorMaximum(Aggregator):
     80     __slots__ = []
     81 
     82     def MergeNewTimedInput(self, newExpiryTime, newValue):
     83         for expiryTime, value in self._sortedInputs:
     84             if expiryTime >= newExpiryTime and value >= newValue:
     85                 return
     86 
     87         result = [ (expiryTime, value) for expiryTime, value in self._sortedInputs if expiryTime < newExpiryTime and value > newValue ]
     88         result.append((newExpiryTime, newValue))
     89         result.extend([ (expiryTime, value) for expiryTime, value in self._sortedInputs if expiryTime > newExpiryTime and value < newValue ])
     90         self._sortedInputs = result
     91 
     92     def _PickValue(self, *values):
     93         return max(values)
     94 
     95 
     96 AGGREGATOR_CLASS_BY_MODE = {'Maximum': AggregatorMaximum,
     97  'Minimum': AggregatorMinimum}
     98 
     99 def CreateAggregator(dbuffCollectionID, expiryTime, outputValue):
    100     dbuffCollection = dbuff.storage.GetDbuffCollection(dbuffCollectionID)
    101     aggregateMode = dbuffCollection.aggregateMode
    102     aggregatorClass = AGGREGATOR_CLASS_BY_MODE[aggregateMode]
    103     return aggregatorClass(expiryTime, outputValue)
    104 
    105 
    106 if __name__ == '__main__':
    107     import random
    108     import timeit
    109 
    110     class AggregatorNull(Aggregator):
    111 
    112         def _PickValue(self, *values):
    113             pass
    114 
    115         def MergeNewTimedInput(self, newExpiryTime, newValue):
    116             pass
    117 
    118 
    119     for aggregator in [AggregatorNull(555, 1.0), AggregatorMaximum(555, 1.0), AggregatorMinimum(555, 1.0)]:
    120         rnd = random.Random('aggregators random seed')
    121         timing = timeit.repeat('\nfor expiryTime, value in samples:\n    aggregator.MergeNewTimedInput(expiryTime, value)\n            ', setup='\nimport random\nfrom __main__ import aggregator, rnd\nnumSamples = 50\nsamples = [(rnd.randint(100, 999), rnd.uniform(0.0, 10.0)) for x in xrange(numSamples)]\n            ', number=10000, repeat=5)
    122         print('%.3fs [%s]' % (min(timing), aggregator))