Ejemplo n.º 1
0
        private static void TestOperationsHelper(bool parallel)
        {
            var map                = new ConcurrentBigMap <int, string>();
            int length             = 100000;
            int expectedAddedCount = length;

            var expectedValues = new string[length];

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

            XAssert.AreEqual(0, map.Count);

            int addedCount = 0;

            // Verify setting bits
            For(length, i =>
            {
                if ((i % 4) == 3)
                {
                    // Introduce some contention for setting the same key.
                    i = i - 1;
                    Interlocked.Decrement(ref expectedAddedCount);
                }

                if ((i % 7) == 3)
                {
                    // Introduce some concurrent read-only operations
                    // in the parallel case
                    map.ContainsKey(i - 2);
                }

                var stringRepresentation = i.ToString();
                if (map.TryAdd(i, stringRepresentation))
                {
                    expectedValues[i] = stringRepresentation;
                    Interlocked.Increment(ref addedCount);
                }

                XAssert.AreEqual(stringRepresentation, map[i]);
            }, parallel);

            XAssert.AreEqual(expectedAddedCount, addedCount);
            XAssert.AreEqual(expectedAddedCount, map.Count);

            For(length, i =>
            {
                XAssert.AreEqual((i % 4) != 3, map.ContainsKey(i));

                var expectedValue = expectedValues[i];
                if (expectedValue != null)
                {
                    XAssert.AreEqual(expectedValue, map[i]);
                }
            }, parallel);
        }
Ejemplo n.º 2
0
        private void ReportDirectoryInputs(Process pip, StreamWriter writer)
        {
            var inputs      = m_observedInputs.ContainsKey(pip.PipId) ? m_observedInputs[pip.PipId] : new List <AbsolutePath>();
            var directories = pip.DirectoryDependencies.Select(directory => directory.Path).ToList();

            if (directories.Count > 0)
            {
                writer.WriteLine("\tDirectory inputs:");

                foreach (var directory in directories)
                {
                    bool headerPrinted = false;

                    writer.WriteLine($"\t\t{directory.ToString(PathTable)}");

                    foreach (var input in inputs)
                    {
                        if (input.IsWithin(PathTable, directory))
                        {
                            if (!headerPrinted)
                            {
                                writer.WriteLine($"\t\tAccessed content:");
                                headerPrinted = true;
                            }
                            writer.WriteLine($"\t\t\t{input.ToString(PathTable)}");
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Removes all bindings to a given value.
        /// </summary>
        public void ClearValue(T value)
        {
            // Run the clear logic in an AddOrUpdate because the HashSet in the value is not thread-safe and this
            // will let the ConcurrentBigMap deal with guarding concurrent access to the HashSet.

            if (m_valueToPathApproximation.ContainsKey(value))
            {
                m_valueToPathApproximation.AddOrUpdate(
                    value,
                    (HashSet <AbsolutePath>)null,
                    (n, nullValue) => new List <AbsolutePath>(),
                    (v, nullValue, paths) =>
                {
                    foreach (var path in paths)
                    {
                        m_pathToValue.AddOrUpdate(
                            path,
                            v,
                            (_, p) => new HashSet <T>(),
                            (p, _, s) =>
                        {
                            s.Remove(v);
                            return(s);
                        });
                    }

                    // For the given node we have cleared all paths so we can simply return an empty list here.
                    return(new List <AbsolutePath>());
                });
            }
        }
 /// <summary>
 /// Add a mapping between variable name and pip id value.
 /// </summary>
 internal void AddPipIdValueMapping(FullSymbol pipIdVariableName, uint pipIdValue)
 {
     Contract.Assert(!m_variableNameToPipIdValueMap.ContainsKey(pipIdVariableName), "Cannot assign the variable name \'" + pipIdVariableName + "\' to more than one pip");
     m_variableNameToPipIdValueMap[pipIdVariableName] = pipIdValue;
     Contract.Assert(!m_pipIdValueToVariableNameMap.ContainsKey(pipIdValue), "Cannot assign more than one variable name to pip id value \'" + pipIdValue + "\'");
     m_pipIdValueToVariableNameMap[pipIdValue] = pipIdVariableName;
 }
 /// <summary>
 /// Add directory mapping, so all pips using the old directory artifact get mapped to the new one.
 /// </summary>
 internal void AddDirectoryMapping(FullSymbol directoryVariableName, DirectoryArtifact mappedDirectory)
 {
     Contract.Assert(!m_variableNameToDirectoryMap.ContainsKey(directoryVariableName), "Cannot assign the variable name \'" + directoryVariableName + "\' to more than one directory");
     m_variableNameToDirectoryMap[directoryVariableName] = mappedDirectory;
     Contract.Assert(!m_directoryToVariableNameMap.ContainsKey(mappedDirectory), "Cannot assign more than one variable name to directory \'" + mappedDirectory + "\'");
     m_directoryToVariableNameMap[mappedDirectory] = directoryVariableName;
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Tries to remove producer.
        /// </summary>
        public bool TryRemoveProducer(PipStableId producer)
        {
            if (m_producedPaths.ContainsKey(producer))
            {
                m_producedPaths.AddOrUpdate(
                    producer,
                    (HashSet <AbsolutePath>)null,
                    (p, nullValue) => new HashSet <AbsolutePath>(),
                    (p, nullValue, existingSet) =>
                {
                    foreach (var path in existingSet)
                    {
                        m_pipProducers.TryRemove(path, out var dummyId);
                    }

                    return(new HashSet <AbsolutePath>());
                });

                return(true);
            }

            return(false);
        }
Ejemplo n.º 7
0
        private (Process process, ContentFingerprint contentFingerprint, string fingerprintText) GetFingerprintInfo(PipReference lazyPip)
        {
            // Make sure the extra event data has set the value properly here.
            Contract.Requires(m_fingerprintSalts.HasValue, "m_fingerprintSalts is not set.");

            Process pip = (Process)lazyPip.HydratePip();
            string  fingerprintText;

            // This checks for missing content info for pips.
            foreach (var dependency in pip.Dependencies)
            {
                if (!m_fileContentMap.ContainsKey(dependency))
                {
                    return(pip, ContentFingerprint.Zero, "FINGERPRINT CONTAINS UNKNOWN DEPENDENCIES");
                }
            }

            if (m_contentFingerprinter == null)
            {
                m_contentFingerprinter = new PipContentFingerprinter(
                    CachedGraph.Context.PathTable,
                    LookupHash,
                    m_fingerprintSalts.Value,
                    pathExpander: m_pathExpander,
                    pipDataLookup: CachedGraph.PipGraph.QueryFileArtifactPipData)
                {
                    FingerprintTextEnabled = true,
                };
            }

            // TODO: Allow specifying fingerprinting version on the command line
            ContentFingerprint fingerprint = m_contentFingerprinter.ComputeWeakFingerprint(
                pip,
                out fingerprintText);

            return(pip, fingerprint, fingerprintText);
        }
Ejemplo n.º 8
0
        public void TestConcurrentBigMapOperations()
        {
            var map = new ConcurrentBigMap <int, string>();

            XAssert.IsTrue(map.TryAdd(0, "value"));
            XAssert.IsFalse(map.TryAdd(0, "not added value"));
            XAssert.AreEqual("value", map[0]);
            map[0] = "newValue";
            map[1] = "value1";

            var value0 = "newValue";

            XAssert.AreEqual(value0, map[0]);
            XAssert.IsTrue(map.ContainsKey(0));
            XAssert.IsTrue(map.ContainsKey(1));
            XAssert.IsFalse(map.ContainsKey(12));

            XAssert.AreEqual(2, map.Count);

            // Test TryGetValue
            string value1;

            XAssert.IsTrue(map.TryGetValue(1, out value1));
            XAssert.AreEqual("value1", value1);
            string value31;

            XAssert.IsFalse(map.TryGetValue(31, out value31));

            // Test update
            XAssert.IsFalse(map.TryUpdate(1, "notUpdatedValue1", "notActualValue1"));
            XAssert.AreEqual("value1", map[1]);
            XAssert.IsTrue(map.TryUpdate(1, "updatedValue1", "value1"));
            value1 = map[1];
            XAssert.AreEqual("updatedValue1", value1);

            // Test remove
            int    beforeFailedRemoveCount = map.Count;
            string value23;

            XAssert.IsFalse(map.TryRemove(23, out value23));
            XAssert.AreEqual(beforeFailedRemoveCount, map.Count);
            map.Add(23, "value23");
            XAssert.AreEqual(beforeFailedRemoveCount + 1, map.Count);
            XAssert.IsTrue(map.TryRemove(23, out value23));
            XAssert.AreEqual("value23", value23);
            XAssert.AreEqual(beforeFailedRemoveCount, map.Count);

            Assert.Equal(new int[] { 0, 1 }, map.Keys.ToArray());
            Assert.Equal(new string[] { value0, value1 }, map.Values.ToArray());

            XAssert.AreEqual(2, map.Count);

            string addedData    = "added data";
            string notAddedData = "not added data";
            var    result       = map.GetOrAdd(2, addedData, (key, data0) => data0);

            XAssert.IsFalse(result.IsFound);
            XAssert.AreEqual(addedData, result.Item.Value);
            XAssert.AreEqual(addedData, map[2]);

            // Ensure entry is not updated for get or add
            result = map.GetOrAdd(2, notAddedData, (key, data0) => data0);
            XAssert.IsTrue(result.IsFound);
            XAssert.AreEqual(addedData, result.Item.Value);
            XAssert.AreEqual(addedData, map[2]);

            Func <int, string, string, string> updateFunction =
                (key, data0, currentValue) => "updated " + currentValue;

            var updatedData = updateFunction(2, notAddedData, addedData);

            result = map.AddOrUpdate(2, notAddedData, (key, data0) => data0, updateFunction);
            XAssert.IsTrue(result.IsFound);
            XAssert.AreEqual(addedData, result.OldItem.Value);
            XAssert.AreEqual(updatedData, result.Item.Value);
            XAssert.AreEqual(updatedData, map[2]);

            result = map.AddOrUpdate(3, addedData, (key, data0) => data0, updateFunction);
            XAssert.IsFalse(result.IsFound);
            XAssert.AreEqual(addedData, result.Item.Value);
            XAssert.AreEqual(addedData, map[3]);

            TestOperationsHelper(parallel: false);
        }
 /// <summary>
 /// Add directory mapping, so all pips using the old directory artifact get mapped to the new one.
 /// </summary>
 public void AddDirectoryMapping(DirectoryArtifact oldDirectory, DirectoryArtifact mappedDirectory)
 {
     Contract.Assert(!m_directoryMap.ContainsKey(oldDirectory), "Cannot map the directory \'" + oldDirectory + "\' to more than one directory");
     m_directoryMap[oldDirectory] = mappedDirectory;
 }
 /// <summary>
 /// Add directory mapping, so all pips using the old directory artifact get mapped to the new one.
 /// </summary>
 public void AddPipIdValueMapping(uint oldPipIdValue, uint mappedPipIdValue)
 {
     Contract.Assert(!m_pipIdValueMap.ContainsKey(oldPipIdValue), "Cannot map the pip id value \'" + oldPipIdValue + "\' to more than one pip id value");
     m_pipIdValueMap[oldPipIdValue] = mappedPipIdValue;
 }
Ejemplo n.º 11
0
 /// <summary>
 /// Checks if symlink definition contains the given path as symlink.
 /// </summary>
 public bool IsSymlink(AbsolutePath path) => m_symlinkDefinitionMap.ContainsKey(path);