using System; using System.Diagnostics; using System.Threading; using glue.Collections.XSpinLock; using glue.Debugging; using glue; #pragma warning disable 0649 namespace agree { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public partial class Strings { FalseSharing.Padding60 fsp1; int next_string_id = 1; FalseSharing.Padding60 fsp2; readonly ConcurrentSymmetricDictionary<String, Int32> dict = new ConcurrentSymmetricDictionary<String, Int32>(); readonly TypeMgr tm; public int string_id; public bool f_petrified = false; public Strings(TypeMgr tm) { this.tm = tm; Nop.X(fsp1, fsp2); } public void Petrify() { f_petrified = true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Guaranteed to preserve the coreference flag and return an _existing_ string mark, if successful /// Implicitly unifies down to *string* (at least) /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public bool Unify(int m_recycle, Edge e1, Edge e2, Tray tr_dst, out Edge result) { //Debug.Assert((e1.FlagsId & Edge.Flag.EtmMask) == Edge.Flag.EtmString || (e2.FlagsId & Edge.Flag.EtmMask) == Edge.Flag.EtmString); int id1 = (int)(e1.FlagsId & tm.MultiIdMask); int id2 = (int)(e2.FlagsId & tm.MultiIdMask); Edge.Flag f_coref = ((e1.FlagsId | e2.FlagsId) & Edge.Flag.Coreference); /// check for e1 not being a string type if ((e1.FlagsId & Edge.Flag.EtmMask) != Edge.Flag.EtmString) { if (!tm.IsTopId(e1) && !tm.CanUnify(string_id, id1)) goto failed; id1 = 0; //goto use_e2; } /// check for e2 not being a string type if ((e2.FlagsId & Edge.Flag.EtmMask) != Edge.Flag.EtmString) { if (!tm.IsTopId(e2) && !tm.CanUnify(string_id, id2)) goto failed; id2 = 0; //goto use_e1; } /// both are some kind of string if (id2 == 0 || id1 == id2) goto use_e1; if (id1 == 0) goto use_e2; failed: result = default(Edge); return false; use_e2: result = tr_dst.CreateRecycledEdge(f_coref | Edge.Flag.EtmString | (Edge.Flag)id2, m_recycle); return true; use_e1: result = tr_dst.CreateRecycledEdge(f_coref | Edge.Flag.EtmString | (Edge.Flag)id1, m_recycle); return true; } public String Get(Int32 sid) { return dict[sid]; } public int GetOrAdd(String s) { return dict.GetOrAdd(s, Interlocked.Increment(ref next_string_id)); } public int Count { get { return dict.Count; } } }; }