示例#1
0
        public static ConcurrentBitArray CraeteBitArrayWithRandomContent(int length)
        {
            var bitArray = new ConcurrentBitArray(length);

            for (int i = 0; i < length; i++)
            {
                if ((s_random.Next(100) % 2) == 0)
                {
                    bitArray.TrySet(i, true);
                }
            }

            return(bitArray);
        }
示例#2
0
        private static void TestOperationsHelper(bool parallel)
        {
            var length    = 256;
            var mod5Array = new ConcurrentBitArray(12);
            var mod8Array = new ConcurrentBitArray(length);

            mod5Array.UnsafeSetLength(length);

            XAssert.AreEqual(length, mod5Array.Length);

            // Verify that all bits start off with the default value (false in this case)
            For(length, i =>
            {
                XAssert.IsFalse(mod5Array[i]);
            }, parallel);

            // Verify setting bits
            For(length, i =>
            {
                mod5Array[i] = i % 5 == 0;
                XAssert.AreEqual(mod5Array[i], i % 5 == 0);
            }, parallel);

            For(length, i =>
            {
                mod8Array[i] = i % 8 == 0;
                XAssert.AreEqual(mod8Array[i], i % 8 == 0);
            }, parallel);

            var orArray = new ConcurrentBitArray(length);

            orArray.Or(mod5Array);
            orArray.Or(mod8Array);

            For(length, i => XAssert.AreEqual(orArray[i], i % 5 == 0 || i % 8 == 0), parallel);

            var andArray = new ConcurrentBitArray(length);

            andArray.Or(mod5Array);
            andArray.And(mod8Array);

            For(length, i => XAssert.AreEqual(andArray[i], i % 5 == 0 && i % 8 == 0), parallel);
        }
示例#3
0
 /// <summary>
 /// Creates a content tracking set for the pip graph
 /// </summary>
 public ContentTrackingSet(PipGraph graph)
 {
     m_graph             = graph;
     m_contentSet        = new ConcurrentBitArray(graph.ContentCount);
     m_serviceContentSet = new ConcurrentBigSet <PipId>();
 }
示例#4
0
        private Task <BoolResult> RegisterLocationAsync(
            OperationContext context,
            IReadOnlyList <ShortHashWithSize> contentHashes,
            MachineId machineId,
            [CallerMemberName] string caller = null)
        {
            const int operationsPerHash = 3;
            var       hashBatchSize     = Math.Max(1, Configuration.RedisBatchPageSize / operationsPerHash);

            return(context.PerformOperationAsync(
                       Tracer,
                       async() =>
            {
                foreach (var page in contentHashes.GetPages(hashBatchSize))
                {
                    var batchResult = await RaidedRedis.ExecuteRedisAsync(context, async(redisDb, token) =>
                    {
                        Counters[GlobalStoreCounters.RegisterLocalLocationHashCount].Add(page.Count);

                        int requiresSetBitCount;
                        ConcurrentBitArray requiresSetBit;

                        if (Configuration.UseOptimisticRegisterLocalLocation)
                        {
                            requiresSetBitCount = 0;
                            requiresSetBit = new ConcurrentBitArray(page.Count);
                            var redisBatch = redisDb.CreateBatch(RedisOperation.RegisterLocalSetNonExistentHashEntries);

                            // Perform initial pass to set redis entries in single operation. Fallback to more elaborate
                            // flow where we use SetBit + KeyExpire
                            foreach (var indexedHash in page.WithIndices())
                            {
                                var hash = indexedHash.value;
                                var key = GetRedisKey(hash.Hash);
                                redisBatch.AddOperationAndTraceIfFailure(context, key, async batch =>
                                {
                                    bool set = await batch.StringSetAsync(key, ContentLocationEntry.ConvertSizeAndMachineIdToRedisValue(hash.Size, machineId), Configuration.LocationEntryExpiry, When.NotExists);
                                    if (!set)
                                    {
                                        requiresSetBit[indexedHash.index] = true;
                                        Interlocked.Increment(ref requiresSetBitCount);
                                    }

                                    return set;
                                }, operationName: "ConvertSizeAndMachineIdToRedisValue");
                            }

                            var result = await redisDb.ExecuteBatchOperationAsync(context, redisBatch, token);
                            if (!result || requiresSetBitCount == 0)
                            {
                                return result;
                            }
                        }
                        else
                        {
                            requiresSetBitCount = page.Count;
                            requiresSetBit = null;
                        }

                        // Some keys already exist and require that we set the bit and update the expiry on the existing entry
                        using (Counters[GlobalStoreCounters.RegisterLocalLocationUpdate].Start())
                        {
                            Counters[GlobalStoreCounters.RegisterLocalLocationUpdateHashCount].Add(requiresSetBitCount);

                            var updateRedisBatch = redisDb.CreateBatch(RedisOperation.RegisterLocalSetHashEntries);

                            foreach (var hash in page.Where((h, index) => requiresSetBit?[index] ?? true))
                            {
                                var key = GetRedisKey(hash.Hash);
                                updateRedisBatch.AddOperationAndTraceIfFailure(
                                    context,
                                    key,
                                    batch => SetLocationBitAndExpireAsync(context, batch, key, hash, machineId),
                                    operationName: "SetLocationBitAndExpireAsync");
                            }

                            return await redisDb.ExecuteBatchOperationAsync(context, updateRedisBatch, token);
                        }
                    }, Configuration.RetryWindow);

                    if (!batchResult)
                    {
                        return batchResult;
                    }
                }

                return BoolResult.Success;
            },
                       Counters[GlobalStoreCounters.RegisterLocalLocation],
                       caller: caller,
                       traceErrorsOnly: true));
        }
示例#5
0
        /// <summary>
        /// Creates a VisitationTracker for a specific graph. Only valid while that graph remains unchanged.
        /// </summary>
        public VisitationTracker(IReadonlyDirectedGraph graph)
        {
            Contract.Requires(graph != null);

            m_visited = new ConcurrentBitArray(graph.NodeCount);
        }
示例#6
0
 /// <nodoc />
 public static RoaringBitSet FromBitArray(ConcurrentBitArray bitArray)
 {
     Contract.Requires(bitArray != null, "bitArray != null");
     return(new RoaringBitSet(bitArray));
 }
示例#7
0
 /// <nodoc />
 private RoaringBitSet(ConcurrentBitArray bitArray)
 {
     m_bitArray = bitArray;
 }
示例#8
0
 /// <nodoc />
 public RoaringBitSet(int length)
 {
     Contract.Requires(length >= 0, "length >= 0");
     m_bitArray = new ConcurrentBitArray(length);
 }
示例#9
0
 /// <nodoc />
 public Enumerator(ConcurrentBitArray bitSet)
     : this()
 {
     m_bitSet       = bitSet;
     m_currentIndex = 0;
 }