//----------------------------------------------------------------------------- // // Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"). // You may not use this file except in compliance with the License. // A copy of the License is located at // // http://aws.amazon.com/apache2.0 // // or in the "license" file accompanying this file. This file is distributed // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either // express or implied. See the License for the specific language governing // permissions and limitations under the License. // //----------------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Linq; using System.Threading; namespace Amazon.XRay.Recorder.Core.Internal.Entities { /// /// A trace subsegment tracks unit of computation within a trace segment (e.g. a method or function) or a downstream call. /// /// [Serializable] public class Subsegment : Entity { private readonly Lazy> _lazyPrecursorIds = new Lazy>(); /// /// Initializes a new instance of the class. /// /// The name. public Subsegment(string name) : base(name) { } /// /// Gets or sets the namespace of the subsegment /// public string Namespace { get; set; } /// /// Gets or sets parent segment /// public Entity Parent { get; set; } /// /// Gets or sets the type /// public string Type { get; set; } /// /// Gets the precursor ids /// public IEnumerable PrecursorIds { get { return _lazyPrecursorIds.Value; } } /// /// Gets a value indicating whether precursor is has been added. /// /// /// true if precursor id has been added; otherwise, false. /// public bool IsPrecursorIdAdded { get { return _lazyPrecursorIds.IsValueCreated && _lazyPrecursorIds.Value.Any(); } } /// /// Add the given precursor id to a set /// /// The precursor id to add to the set /// true if the id is added; false if the id is already present. /// The given precursor id is not a valid segment id. public bool AddPrecursorId(string precursorId) { if (!Entity.IsIdValid(precursorId)) { throw new ArgumentException("The precursor id is not a valid segment id: ", precursorId); } bool ret; lock (_lazyPrecursorIds.Value) { ret = _lazyPrecursorIds.Value.Add(precursorId); } return ret; } /// /// Check if this segment or the root segment that this segment belongs to is ok to emit /// /// If the segment is ready to emit public override bool IsEmittable() { return Reference == 0 && Parent != null && Parent.IsEmittable(); } /// /// Release reference to this instance of segment /// /// Reference count after release public override long Release() { long count = DecrementReferenceCounter(); if (count == 0 && Parent != null) { Parent.Release(); } return count; } } }