public TimeBasedIdentity GetNewID(DateTime time)
        {
            long diffSeconds = DateTimeHelper
                               .SecondsDiff
                                   (_basedDateTime, time);
            long periodID    = (diffSeconds / _periodInSeconds);
            long periodModID = periodID % _periodsMaxCount;
            int  secondID    = (int)(diffSeconds % _periodInSeconds);
            int  l           = PeriodsSeedsBuckets.Length;
            long bucketID    = periodModID % l;
            TimeBasedIdentity timeBasedIdentity = PeriodsSeedsBuckets[bucketID];
            //timeBasedIdentity.SecondID = secondID;
            TimeBasedIdentity r = null;

            if
            (
                timeBasedIdentity.PeriodModID == periodModID
            )
            {
                r              = timeBasedIdentity.PartialClone();
                r.SecondID     = secondID;
                r.IdentityTime = r.PeriodAlignedTime.AddSeconds(secondID);
            }
            return(r);
        }
        private bool InitializeNextOnePeriodDataProcessAction()
        {
            var r   = false;
            var now = DateTime.Now;
            //now = DateTime.Parse("9999-12-31 23:10:00");
            //周期标识
            var diffSeconds = DateTimeHelper
                              .SecondsDiff(_basedDateTime, now);
            long periodID    = (diffSeconds / _periodInSeconds);
            var  alignedTime = _basedDateTime
                               .AddSeconds
                                   (periodID * _periodInSeconds);

            periodID++;
            var  periodModID     = periodID % _periodsMaxCount;
            int  l               = PeriodsSeedsBuckets.Length;
            long bucketID        = periodID % l;
            var  lastPeriodID    = PeriodsSeedsBuckets[bucketID].PeriodID;
            var  lastPeriodModID = PeriodsSeedsBuckets[bucketID].PeriodModID;

            if
            (
                periodID > lastPeriodID
                &&
                periodModID != lastPeriodModID
            )
            {
                PeriodsSeedsBuckets[bucketID]
                    = new TimeBasedIdentity
                      (
                          periodID
                          , periodModID
                          , new int[_periodInSeconds]
                          , alignedTime
                          , DateTime.Now
                          , _basedDateTime
                          , _periodInSeconds
                          , _periodsMaxCount
                          , _initializePeriodsCount
                      );
                r = true;
            }
            return(r);
        }
 private bool InitializeNextOnePeriodDataProcessAction()
 {
     var r = false;
     var now = DateTime.Now;
     //now = DateTime.Parse("9999-12-31 23:10:00");
     //周期标识
     var diffSeconds = DateTimeHelper
                             .SecondsDiff(_basedDateTime, now);
     long periodID = (diffSeconds / _periodInSeconds);
     var alignedTime = _basedDateTime
                             .AddSeconds
                                 (periodID * _periodInSeconds);
     periodID++;
     var periodModID = periodID % _periodsMaxCount;
     int l = PeriodsSeedsBuckets.Length;
     long bucketID = periodID % l;
     var lastPeriodID = PeriodsSeedsBuckets[bucketID].PeriodID;
     var lastPeriodModID = PeriodsSeedsBuckets[bucketID].PeriodModID;
     if
         (
             periodID > lastPeriodID
             &&
             periodModID != lastPeriodModID
         )
     {
         PeriodsSeedsBuckets[bucketID]
                         = new TimeBasedIdentity
                                 (
                                     periodID
                                     , periodModID
                                     , new int[_periodInSeconds]
                                     , alignedTime
                                     , DateTime.Now
                                     , _basedDateTime
                                     , _periodInSeconds
                                     , _periodsMaxCount
                                     , _initializePeriodsCount
                                 );
         r = true;
     }
     return r;
 }
        public TimeBasedIdentityGenerator
                    (
                        long periodInSeconds = 86400
                        , int periodsMaxCount = 10000
                        , int initializeMinPeriodsBucketsCount = 2
                        , Action<TimeBasedIdentityGenerator> onAfterDataInitializedProcessAction = null
                        , DateTime basedDateTime = default(DateTime)
                        , int checkTimes = 2
                    )
        {

            _basedDateTime = basedDateTime;
            _periodInSeconds = periodInSeconds;
            _periodsMaxCount = periodsMaxCount;
            var remainder = _periodsMaxCount % initializeMinPeriodsBucketsCount;
            if (remainder != 0)
            {
                while (_periodsMaxCount % (++initializeMinPeriodsBucketsCount) != 0) ;
            }
            //桶个数
            _initializePeriodsCount = initializeMinPeriodsBucketsCount;
            var diffSeconds = DateTimeHelper
                                    .SecondsDiff
                                        (_basedDateTime, DateTime.Now);
            PeriodsSeedsBuckets = new TimeBasedIdentity[_initializePeriodsCount];
            var l = PeriodsSeedsBuckets.Length;
            long periodID = (diffSeconds / _periodInSeconds);
            for (int i = 0; i < l; i++)
            {
                var periodModID = periodID % _periodsMaxCount;
                var alignedTime = _basedDateTime
                                    .AddSeconds
                                        (periodID * _periodInSeconds);
                PeriodsSeedsBuckets[periodModID % l]
                                        = new TimeBasedIdentity
                                                    (
                                                        periodID
                                                        , periodModID
                                                        , new int[_periodInSeconds]
                                                        , alignedTime
                                                        , DateTime.Now
                                                        , _basedDateTime
                                                        , _periodInSeconds
                                                        , _periodsMaxCount
                                                        , _initializePeriodsCount
                                                    );
                periodID++;
                //periodModID++;
                //periodModID = periodModID % _periodsMaxCount;
            }
            if (onAfterDataInitializedProcessAction != null)
            {
                onAfterDataInitializedProcessAction(this);
            }
            int timerIntervalInSeconds = (int)_periodInSeconds / checkTimes;
            new EasyTimer
                    (
                        timerIntervalInSeconds
                        , 2
                        , (x) =>
                        {
                            if (InitializeNextOnePeriodDataProcessAction())
                            {
                                if (onAfterDataInitializedProcessAction != null)
                                {
                                    onAfterDataInitializedProcessAction(this);
                                }
                            }
                        }
                    ).Start();
        }
        public TimeBasedIdentityGenerator
        (
            long periodInSeconds  = 86400
            , int periodsMaxCount = 10000
            , int initializeMinPeriodsBucketsCount = 2
            , Action <TimeBasedIdentityGenerator> onAfterDataInitializedProcessAction = null
            , DateTime basedDateTime = default(DateTime)
            , int checkTimes         = 2
        )
        {
            _basedDateTime   = basedDateTime;
            _periodInSeconds = periodInSeconds;
            _periodsMaxCount = periodsMaxCount;
            var remainder = _periodsMaxCount % initializeMinPeriodsBucketsCount;

            if (remainder != 0)
            {
                while (_periodsMaxCount % (++initializeMinPeriodsBucketsCount) != 0)
                {
                    ;
                }
            }
            //桶个数
            _initializePeriodsCount = initializeMinPeriodsBucketsCount;
            var diffSeconds = DateTimeHelper
                              .SecondsDiff
                                  (_basedDateTime, DateTime.Now);

            PeriodsSeedsBuckets = new TimeBasedIdentity[_initializePeriodsCount];
            var  l        = PeriodsSeedsBuckets.Length;
            long periodID = (diffSeconds / _periodInSeconds);

            for (int i = 0; i < l; i++)
            {
                var periodModID = periodID % _periodsMaxCount;
                var alignedTime = _basedDateTime
                                  .AddSeconds
                                      (periodID * _periodInSeconds);
                PeriodsSeedsBuckets[periodModID % l]
                    = new TimeBasedIdentity
                      (
                          periodID
                          , periodModID
                          , new int[_periodInSeconds]
                          , alignedTime
                          , DateTime.Now
                          , _basedDateTime
                          , _periodInSeconds
                          , _periodsMaxCount
                          , _initializePeriodsCount
                      );
                periodID++;
                //periodModID++;
                //periodModID = periodModID % _periodsMaxCount;
            }
            if (onAfterDataInitializedProcessAction != null)
            {
                onAfterDataInitializedProcessAction(this);
            }
            int timerIntervalInSeconds = (int)_periodInSeconds / checkTimes;

            new EasyTimer
            (
                timerIntervalInSeconds
                , 2
                , (x) =>
            {
                if (InitializeNextOnePeriodDataProcessAction())
                {
                    if (onAfterDataInitializedProcessAction != null)
                    {
                        onAfterDataInitializedProcessAction(this);
                    }
                }
            }
            ).Start();
        }