2016-10-13 19:35:55 +02:00
|
|
|
from zope.interface import implementer
|
2016-10-06 04:58:34 +02:00
|
|
|
from decimal import Decimal
|
2016-09-27 19:52:44 +02:00
|
|
|
|
2016-10-13 19:35:55 +02:00
|
|
|
from lbrynet.interfaces import IBlobPriceModel
|
2016-12-21 20:55:43 +01:00
|
|
|
from lbrynet import conf
|
2016-10-13 19:35:55 +02:00
|
|
|
|
2016-09-27 19:52:44 +02:00
|
|
|
|
2016-10-13 19:35:55 +02:00
|
|
|
def get_default_price_model(blob_tracker, base_price, **kwargs):
|
|
|
|
return MeanAvailabilityWeightedPrice(blob_tracker, base_price, **kwargs)
|
2016-10-03 08:44:58 +02:00
|
|
|
|
|
|
|
|
2016-09-27 19:52:44 +02:00
|
|
|
class MeanAvailabilityWeightedPrice(object):
|
2016-11-30 21:20:45 +01:00
|
|
|
"""Calculate mean-blob-availability and stream-position weighted price for a blob
|
2016-09-27 19:52:44 +02:00
|
|
|
|
|
|
|
Attributes:
|
2016-10-13 19:35:55 +02:00
|
|
|
base_price (float): base price
|
2016-11-30 21:20:45 +01:00
|
|
|
alpha (float): constant, > 0.0 and <= 1.0, used to more highly
|
|
|
|
value blobs at the beginning of a stream.
|
2016-10-13 19:35:55 +02:00
|
|
|
alpha defaults to 1.0, which has a null effect
|
2016-09-27 19:52:44 +02:00
|
|
|
blob_tracker (BlobAvailabilityTracker): blob availability tracker
|
2016-11-30 21:20:45 +01:00
|
|
|
|
2016-09-27 19:52:44 +02:00
|
|
|
"""
|
2016-10-13 19:35:55 +02:00
|
|
|
implementer(IBlobPriceModel)
|
2016-09-27 19:52:44 +02:00
|
|
|
|
2016-12-21 20:55:43 +01:00
|
|
|
def __init__(self, tracker, base_price=None, alpha=1.0):
|
2016-09-27 19:52:44 +02:00
|
|
|
self.blob_tracker = tracker
|
2016-12-21 20:55:43 +01:00
|
|
|
base_price = base_price if base_price is not None else conf.settings.data_rate
|
2016-10-06 04:58:34 +02:00
|
|
|
self.base_price = Decimal(base_price)
|
|
|
|
self.alpha = Decimal(alpha)
|
2016-09-27 19:52:44 +02:00
|
|
|
|
|
|
|
def calculate_price(self, blob):
|
|
|
|
mean_availability = self.blob_tracker.last_mean_availability
|
|
|
|
availability = self.blob_tracker.availability.get(blob, [])
|
2016-10-03 08:44:58 +02:00
|
|
|
index = 0 # blob.index
|
2016-11-30 21:20:45 +01:00
|
|
|
availability_mult = self._get_availability_multiplier(mean_availability, availability)
|
|
|
|
price = self.base_price * availability_mult / self._frontload(index)
|
2016-10-03 08:44:58 +02:00
|
|
|
return round(price, 5)
|
2016-09-27 19:52:44 +02:00
|
|
|
|
2016-10-20 07:35:18 +02:00
|
|
|
def _get_availability_multiplier(self, mean_availability, availability):
|
|
|
|
return Decimal(max(1, mean_availability) / Decimal(max(1, len(availability))))
|
|
|
|
|
2016-09-27 19:52:44 +02:00
|
|
|
def _frontload(self, index):
|
2016-11-30 21:20:45 +01:00
|
|
|
"""Get front-load multiplier, used to weight prices of blobs in a
|
|
|
|
stream towards the front of the stream.
|
2016-10-13 19:35:55 +02:00
|
|
|
|
|
|
|
At index 0, returns 1.0
|
|
|
|
As index increases, return value approaches 2.0
|
2016-09-27 19:52:44 +02:00
|
|
|
|
|
|
|
@param index: blob position in stream
|
2016-10-13 19:35:55 +02:00
|
|
|
@return: front-load multiplier
|
2016-11-30 21:20:45 +01:00
|
|
|
|
2016-09-27 19:52:44 +02:00
|
|
|
"""
|
|
|
|
|
2016-10-06 04:58:34 +02:00
|
|
|
return Decimal(2.0) - (self.alpha ** index)
|