Esempio n. 1
0
        public StreamBlockProxy TryRentIndexedStreamBlockProxy(StreamLog streamLog, StreamBlockRecord record)
        {
            StreamBlockProxy p = null;

            while (p == null)
            {
                var blockKey = new BlockKey(streamLog.Slid, record.Version);
                // ReSharper disable once InconsistentlySynchronizedField
                if (_blocks.TryGetValue(blockKey, out var handle))
                {
                    p = handle.Target as StreamBlockProxy;
                }
                else
                {
                    // CD.GetOrAdd factory is not atomic, lock manually.
                    // Lock on SL, not a global object. This also helps
                    // to avoid a capturing lambda and the risk of collecting
                    // an object held only by a weak reference during that lambda return.
                    lock (streamLog)
                    {
                        if (_blocks.TryGetValue(blockKey, out handle))
                        {
                            p = handle.Target as StreamBlockProxy;
                        }
                        else
                        {
                            p = StreamBlockProxy.Create(blockKey, this);

                            var sb = streamLog.GetBlockFromRecord(record);

                            // Could set directly without SetStreamBlock
                            p.Block = sb;
                            handle  = GCHandle.Alloc(p, GCHandleType.Weak);
                            if (!_blocks.TryAdd(blockKey, handle))
                            {
                                // this should never happen unless there are different streamLog instances for the same slid,
                                // which in turn should never happen because SLs are stored in SLM dictionary.
                                ThrowHelper.FailFast("Cannot add newly created StreamBlockProxy to cache from inside a lock.");
                            }
                        }
                    }
                }

                // will be null if cannot retain, then will start over
                p = p?.TryRetain();
            }

            return(p);
        }
        public bool GetIsCompleted(StreamLogId streamLogId)
        {
            var streamId = (long)streamLogId;

            using (var txn = Environment.BeginReadOnlyTransaction())
                using (var c = _blocksDb.OpenReadOnlyCursor(txn))
                {
                    StreamBlockRecord value = default;
                    if (c.TryGet(ref streamId, ref value, CursorGetOption.Set) &&
                        c.TryGet(ref streamId, ref value, CursorGetOption.LastDuplicate))
                    {
                        return(value.Version == CompletedVersion);
                    }
                    return(false);
                }
        }
Esempio n. 3
0
        internal StreamBlock GetBlockFromRecord(StreamBlockRecord record)
        {
            StreamBlock block;

            // we cannot touch a block when it is stored
            if (record.BufferRef != default)
            {
#pragma warning disable 618
                block = StreamLogManager.BlockIndex.TryRentIndexedStreamBlock(this, record.BufferRef);
#pragma warning restore 618

                if (block.IsValid || record.Version == StreamBlockIndex.ReadyBlockVersion)
                {
                    return(block);
                }

                // TODO (!) review why this was needed, sometimes we get "cannot get block that should exists", probably this is the fix
                //if (_streamLog.StreamLogManager.BlockIndex.TryGetValue(StreamLogId, record.Version, out record)
                //    && record.BufferRef != default && !record.BufferRef.Flag
                //)
                //{
                //    FailCannotGetChunk(record);
                //}
            }
            // throw new NotImplementedException(); // TODO Storage
            block =
                StreamLogManager
                .BlockIndex
                .BlockStorage
                .TryGetStreamBlock((long)Slid, record.Version);

            if (block.IsValid)
            {
                return(block);
            }

            FailCannotGetBlock();
            return(default);