public void IncrementPrint(Advertiser adv, DateTime date)
        {
            ulong[]      hourlyPrints = null;
            DbAdvertiser dbAdv        = null;
            var          lockTaken    = false;

            _cachedDataSpinLock.Enter(ref lockTaken);
            if (_hourlyPrints.ContainsKey(adv.Id))
            {
                hourlyPrints = _hourlyPrints[adv.Id];
                dbAdv        = _cachedData[adv.Id];
            }
            if (lockTaken)
            {
                _cachedDataSpinLock.Exit();
            }

            if (hourlyPrints != null)
            {
                var hourIndex = _dateTimeService.GetCurrentDateTime().Hour - date.Hour;
                if (hourIndex < 0)
                {
                    hourIndex += 24;
                }

                var lastModified = Interlocked.Increment(ref hourlyPrints[hourIndex]);
                if (hourIndex == 0) //current
                {
                    dbAdv.CurrentHourlyPrints = lastModified;
                }
            }
        }
        public Advertiser Build(DbAdvertiser repoAdv, DateTime dateTime)
        {
            var adv = new Advertiser();

            //Discard disabled
            if (!repoAdv.Enabled)
            {
                return(null);
            }
            //discard hitted HourlyBudget
            if ((repoAdv.CurrentHourlyPrints / (decimal)1000) * repoAdv.CPM >= repoAdv.MaxHourlyBudget)
            {
                return(null);
            }
            //Skip not available
            if (repoAdv.WorkingCalendar != null)
            {
                if (!repoAdv.WorkingCalendar.ContainsKey((byte)dateTime.DayOfWeek))
                {
                    return(null);
                }
                if (!repoAdv.WorkingCalendar[(byte)dateTime.DayOfWeek].Contains(dateTime.Hour))
                {
                    return(null);
                }
            }

            //optional Tags are not needed

            adv.RequiredTagsHashSetsFull = new HashSet <Tag>();
            for (int i = 0; i < repoAdv.RequiredTags.Count; i++)
            {
                adv.RequiredTagsHashSetsFull.Add(repoAdv.RequiredTags[i]);
            }
            adv.RequiredTagsCount = repoAdv.RequiredTags.Count;

            adv.RejectedTagsHashSetsFull = new HashSet <Tag>();
            for (int i = 0; i < repoAdv.RejectedTags.Count; i++)
            {
                adv.RejectedTagsHashSetsFull.Add(repoAdv.RejectedTags[i]);
            }

            adv.RequiredTagsHashSetsFull.TrimExcess();
            adv.RejectedTagsHashSetsFull.TrimExcess();

            adv.CPM = repoAdv.CPM;
            adv.Id  = repoAdv.Id;
            return(adv);
        }