Ejemplo n.º 1
0
        public ContentStore(IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor, ILogger logger, BPlusTree <int, ContentNodeKit> localDb = null)
        {
            _publishedSnapshotAccessor = publishedSnapshotAccessor;
            _variationContextAccessor  = variationContextAccessor;
            _logger  = logger;
            _localDb = localDb;

            _contentNodes        = new ConcurrentDictionary <int, LinkedNode <ContentNode> >();
            _contentRootNodes    = new ConcurrentDictionary <int, LinkedNode <object> >();
            _contentTypesById    = new ConcurrentDictionary <int, LinkedNode <PublishedContentType> >();
            _contentTypesByAlias = new ConcurrentDictionary <string, LinkedNode <PublishedContentType> >(StringComparer.InvariantCultureIgnoreCase);
            _xmap = new ConcurrentDictionary <Guid, int>();

            _genRefRefs  = new ConcurrentQueue <GenRefRef>();
            _genRefRef   = null;  // no initial gen exists
            _liveGen     = _floorGen = 0;
            _nextGen     = false; // first time, must create a snapshot
            _collectAuto = true;  // collect automatically by default
        }
Ejemplo n.º 2
0
        public Snapshot CreateSnapshot()
        {
            var lockInfo = new ReadLockInfo();

            try
            {
                Lock(lockInfo);

                // if no next generation is required, and we already have one,
                // use it and create a new snapshot
                if (_nextGen == false && _genRefRef != null)
                {
                    return(new Snapshot(this, _genRefRef.GetGenRef()
#if DEBUG
                                        , _logger
#endif
                                        ));
                }

                // else we need to try to create a new gen ref
                // whether we are wlocked or not, noone can rlock while we do,
                // so _liveGen and _nextGen are safe
                if (_wlocked > 0) // volatile, cannot ++ but could --
                {
                    // write-locked, cannot use latest gen (at least 1) so use previous
                    var snapGen = _nextGen ? _liveGen - 1 : _liveGen;

                    // create a new gen ref unless we already have it
                    if (_genRefRef == null)
                    {
                        _genRefRefs.Enqueue(_genRefRef = new GenRefRef(snapGen));
                    }
                    else if (_genRefRef.Gen != snapGen)
                    {
                        throw new Exception("panic");
                    }
                }
                else
                {
                    // not write-locked, can use latest gen, create a new gen ref
                    _genRefRefs.Enqueue(_genRefRef = new GenRefRef(_liveGen));
                    _nextGen = false; // this is the ONLY thing that triggers a _liveGen++
                }

                // so...
                // the genRefRef has a weak ref to the genRef, and is queued
                // the snapshot has a ref to the genRef, which has a ref to the genRefRef
                // when the snapshot is disposed, it decreases genRefRef counter
                // so after a while, one of these conditions is going to be true:
                // - the genRefRef counter is zero because all snapshots have properly been disposed
                // - the genRefRef weak ref is dead because all snapshots have been collected
                // in both cases, we will dequeue and collect

                var snapshot = new Snapshot(this, _genRefRef.GetGenRef()
#if DEBUG
                                            , _logger
#endif
                                            );

                // reading _floorGen is safe if _collectTask is null
                if (_collectTask == null && _collectAuto && _liveGen - _floorGen > CollectMinGenDelta)
                {
                    CollectAsyncLocked();
                }

                return(snapshot);
            }
            finally
            {
                Release(lockInfo);
            }
        }
Ejemplo n.º 3
0
 public GenRef(GenRefRef genRefRef, long gen)
 {
     GenRefRef = genRefRef;
     Gen       = gen;
 }