/// <summary> /// Adds an entry without RW lock. /// </summary> private void AddNoLock(DataStreamerClientEntry <TK, TV> entry) { var retries = MaxRetries; while (!_cancelled) { try { var socket = _socket.GetAffinitySocket(_cacheId, entry.Key) ?? _socket.GetSocket(); var buffer = GetOrAddPerNodeBuffer(socket); if (buffer.Add(entry)) { return; } } catch (Exception e) { if (ShouldRetry(e) && retries-- > 0) { continue; } throw; } } }
/// <summary> /// Gets the pooled entry array. /// </summary> internal DataStreamerClientEntry <TK, TV>[] GetPooledArray() { DataStreamerClientEntry <TK, TV>[] res; if (_arrayPool.TryPop(out res)) { // Reset buffer and return. Array.Clear(res, 0, res.Length); return(res); } Interlocked.Increment(ref _arraysAllocated); res = new DataStreamerClientEntry <TK, TV> [_options.PerNodeBufferSize]; return(res); }
/// <summary> /// Adds an entry to the streamer. /// </summary> private void Add(DataStreamerClientEntry <TK, TV> entry) { if (!_rwLock.TryEnterReadLock(0)) { throw new ObjectDisposedException("DataStreamerClient", "Data streamer has been disposed"); } try { ThrowIfClosed(); AddNoLock(entry); } finally { _rwLock.ExitReadLock(); } }
/// <summary> /// Adds an entry to the buffer. /// </summary> public bool Add(DataStreamerClientEntry <TK, TV> entry) { if (!_rwLock.TryEnterReadLock(0)) { return(false); } try { if (_closed) { return(false); } while (true) { var buffer = _buffer; if (buffer.Add(entry)) { return(true); } var entryArray = _client.GetPooledArray(); #pragma warning disable 0420 // A reference to a volatile field will not be treated as volatile (not a problem) if (Interlocked.CompareExchange(ref _buffer, new DataStreamerClientBuffer <TK, TV>(entryArray, this, buffer), buffer) != buffer) { _client.ReturnPooledArray(entryArray); } #pragma warning restore 0420 // A reference to a volatile field will not be treated as volatile } } finally { _rwLock.ExitReadLock(); } }
/// <summary> /// Adds an entry to the buffer. /// </summary> /// <param name="entry">Entry.</param> /// <returns>True when added successfully; false otherwise (buffer is full, flushing, flushed, or closed).</returns> public bool Add(DataStreamerClientEntry <TK, TV> entry) { if (!_rwLock.TryEnterReadLock(0)) { return(false); } long newSize; try { if (_flushing || _flushed) { return(false); } newSize = Interlocked.Increment(ref _size); if (newSize > _entries.Length) { return(false); } _entries[newSize - 1] = entry; } finally { _rwLock.ExitReadLock(); } if (newSize == _entries.Length) { TryStartFlush(); } return(true); }