/// <summary> /// Validates the specified <see cref="IIndexUser"/>. /// The <paramref name="user"/> is added to <see cref="_users"/> /// if the user isn't known by the current <see cref="IndexGenerator"/>. /// </summary> /// <param name="user"></param> private void RegisterUser(IIndexUser user) { using (_usersLock.EnterDisposableUpgradeableReadLock()) if (!_users.Contains(user)) { using (_usersLock.EnterDisposableWriteLock()) _users.Add(user); } }
/// <summary> /// Returns the first free index. /// </summary> /// <param name="indexRequester">The object requesting the new key, usually the object invoking this method.</param> /// <returns></returns> public uint Next(IIndexUser indexRequester) { RegisterUser(indexRequester); lock (_indicesLock) { while (_freeIndices.Count != 0) { var freeIndex = _freeIndices[_freeIndices.Count - 1]; _freeIndices.RemoveAt(_freeIndices.Count - 1); if (!IsInUse(freeIndex)) { return(freeIndex); } } // ELSE: find a new index. do { _currentIndex++; } while (IsInUse(_currentIndex)); return(_currentIndex); } }
/// <summary> /// Detaches the specified <see cref="IIndexUser"/> from the current <see cref="IndexGenerator"/>. /// This means that new indices, generated with <see cref="Next"/>, will not be verified anymore /// from <paramref name="indexUser"/> and may thereby be simultaneously used by the detached object. /// </summary> /// <param name="indexUser">The <see cref="IIndexUser"/> to detach.</param> /// <returns> /// True if the specified <see cref="IIndexUser"/> was successfully detached from the <see cref="IndexGenerator"/>; otherwise, false. /// This method also returns false if the <paramref name="indexUser"/> is not found to be registered with the current <see cref="IndexGenerator"/>. /// </returns> public bool Detach(IIndexUser indexUser) { using (_usersLock.EnterDisposableWriteLock()) return(_users.Remove(indexUser)); }
/// <summary> /// Validates the specified <see cref="IIndexUser"/>. /// The <paramref name="user"/> is added to <see cref="_users"/> /// if the user isn't known by the current <see cref="IndexGenerator"/>. /// </summary> /// <param name="user"></param> private void RegisterUser(IIndexUser user) { using (_usersLock.EnterDisposableUpgradeableReadLock()) if (!_users.Contains(user)) using (_usersLock.EnterDisposableWriteLock()) _users.Add(user); }
/// <summary> /// Detaches the specified <see cref="IIndexUser"/> from the current <see cref="IndexGenerator"/>. /// This means that new indices, generated with <see cref="Next"/>, will not be verified anymore /// from <paramref name="indexUser"/> and may thereby be simultaneously used by the detached object. /// </summary> /// <param name="indexUser">The <see cref="IIndexUser"/> to detach.</param> /// <returns> /// True if the specified <see cref="IIndexUser"/> was successfully detached from the <see cref="IndexGenerator"/>; otherwise, false. /// This method also returns false if the <paramref name="indexUser"/> is not found to be registered with the current <see cref="IndexGenerator"/>. /// </returns> public bool Detach(IIndexUser indexUser) { using (_usersLock.EnterDisposableWriteLock()) return _users.Remove(indexUser); }
/// <summary> /// Returns the first free index. /// </summary> /// <param name="indexRequester">The object requesting the new key, usually the object invoking this method.</param> /// <returns></returns> public uint Next(IIndexUser indexRequester) { RegisterUser(indexRequester); lock (_indicesLock) { while (_freeIndices.Count != 0) { var freeIndex = _freeIndices[_freeIndices.Count - 1]; _freeIndices.RemoveAt(_freeIndices.Count - 1); if (!IsInUse(freeIndex)) return freeIndex; } // ELSE: find a new index. do { _currentIndex++; } while (IsInUse(_currentIndex)); return _currentIndex; } }