using Disco.Data.Repository; using Disco.Models.Repository; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Disco.Services.Jobs.JobQueues { internal class Cache { private ConcurrentDictionary _Cache; private Dictionary> _SubjectCache; private ReadOnlyCollection> _Icons; private ReadOnlyCollection> _IconColourCache; private ReadOnlyCollection> _SlaOptions; public Cache(DiscoDataContext Database) { Initialize(Database); } private void Initialize(DiscoDataContext Database) { // Queues from Database var queues = Database.JobQueues.ToList(); // Default System Queue //var defaultQueue = new JobQueue() //{ // Id = 0, // Name = "Default Queue", // Description = "Default system queue for orphaned jobs", // Icon = "question-circle", // IconColour = "F0A30A", // DefaultSLAExpiry = null, // Priority = JobQueuePriority.Normal, // SubjectIds = null //}; //queues.Add(defaultQueue); // Add Queues to In-Memory Cache this._Cache = new ConcurrentDictionary(queues.Select(q => new KeyValuePair(q.Id, JobQueueToken.FromJobQueue(q)))); // Calculate Queue Subject Cache CalculateSubjectCache(); #region Predefined Options // Icons if (this._Icons == null) { this._Icons = new List>(){ new KeyValuePair("ambulance" , "Ambulance"), new KeyValuePair("anchor" , "Anchor"), new KeyValuePair("android" , "Android"), new KeyValuePair("apple" , "Apple"), new KeyValuePair("archive" , "Archive"), new KeyValuePair("arrow-circle-down" , "Arrow Circle Down"), new KeyValuePair("arrow-circle-left" , "Arrow Circle Left"), new KeyValuePair("arrow-circle-right" , "Arrow Circle Right"), new KeyValuePair("arrow-circle-up" , "Arrow Circle Up"), new KeyValuePair("asterisk" , "Asterisk"), new KeyValuePair("ban" , "Ban"), new KeyValuePair("beer" , "Beer"), new KeyValuePair("bell" , "Bell"), new KeyValuePair("bolt" , "Bolt"), new KeyValuePair("book" , "Book"), new KeyValuePair("bookmark" , "Bookmark"), new KeyValuePair("briefcase" , "Briefcase"), new KeyValuePair("bug" , "Bug"), new KeyValuePair("building-o" , "Building"), new KeyValuePair("bullhorn" , "Bullhorn"), new KeyValuePair("bullseye" , "Bullseye"), new KeyValuePair("calendar" , "Calendar"), new KeyValuePair("calendar-o" , "Calendar"), new KeyValuePair("check-circle" , "Check Circle"), new KeyValuePair("clock-o" , "Clock"), new KeyValuePair("cloud" , "Cloud"), new KeyValuePair("coffee" , "Coffee"), new KeyValuePair("comments" , "Comments"), new KeyValuePair("compass" , "Compass"), new KeyValuePair("credit-card" , "Credit Card"), new KeyValuePair("crosshairs" , "Crosshairs"), new KeyValuePair("desktop" , "Desktop"), new KeyValuePair("dollar" , "Dollar"), new KeyValuePair("dot-circle-o" , "Dot Circle"), new KeyValuePair("envelope" , "Envelope"), new KeyValuePair("exclamation" , "Exclamation"), new KeyValuePair("eye" , "Eye"), new KeyValuePair("female" , "Female"), new KeyValuePair("fighter-jet" , "Fighter Jet"), new KeyValuePair("film" , "Film"), new KeyValuePair("filter" , "Filter"), new KeyValuePair("fire" , "Fire"), new KeyValuePair("fire-extinguisher" , "Fire Extinguisher"), new KeyValuePair("flask" , "Flask"), new KeyValuePair("frown-o" , "Frown"), new KeyValuePair("gamepad" , "Gamepad"), new KeyValuePair("gift" , "Gift"), new KeyValuePair("glass" , "Glass"), new KeyValuePair("globe" , "Globe"), new KeyValuePair("hand-o-down" , "Hand Down"), new KeyValuePair("hand-o-left" , "Hand Left"), new KeyValuePair("hand-o-right" , "Hand Right"), new KeyValuePair("hand-o-up" , "Hand Up"), new KeyValuePair("hdd-o" , "Hdd"), new KeyValuePair("heart" , "Heart"), new KeyValuePair("home" , "Home"), new KeyValuePair("info" , "Info"), new KeyValuePair("key" , "Key"), new KeyValuePair("keyboard-o" , "Keyboard"), new KeyValuePair("laptop" , "Laptop"), new KeyValuePair("leaf" , "Leaf"), new KeyValuePair("legal" , "Legal"), new KeyValuePair("lightbulb-o" , "Lightbulb"), new KeyValuePair("linux" , "Linux"), new KeyValuePair("location-arrow" , "Location Arrow"), new KeyValuePair("magnet" , "Magnet"), new KeyValuePair("male" , "Male"), new KeyValuePair("map-marker" , "Map Marker"), new KeyValuePair("medkit" , "Medkit"), new KeyValuePair("meh-o" , "Meh"), new KeyValuePair("microphone" , "Microphone"), new KeyValuePair("microphone-slash" , "Microphone Slash"), new KeyValuePair("minus-circle" , "Minus Circle"), new KeyValuePair("mobile" , "Mobile"), new KeyValuePair("money" , "Money"), new KeyValuePair("moon-o" , "Moon"), new KeyValuePair("music" , "Music"), new KeyValuePair("paperclip" , "Paperclip"), new KeyValuePair("pencil" , "Pencil"), new KeyValuePair("phone" , "Phone"), new KeyValuePair("picture-o" , "Picture"), new KeyValuePair("plane" , "Plane"), new KeyValuePair("power-off" , "Power Off"), new KeyValuePair("print" , "Print"), new KeyValuePair("puzzle-piece" , "Puzzle Piece"), new KeyValuePair("question" , "Question"), new KeyValuePair("question-circle" , "Question Circle"), new KeyValuePair("random" , "Random"), new KeyValuePair("retweet" , "Retweet"), new KeyValuePair("road" , "Road"), new KeyValuePair("rocket" , "Rocket"), new KeyValuePair("shield" , "Shield"), new KeyValuePair("shopping-cart" , "Shopping Cart"), new KeyValuePair("smile-o" , "Smile"), new KeyValuePair("star" , "Star"), new KeyValuePair("suitcase" , "Suitcase"), new KeyValuePair("sun-o" , "Sun"), new KeyValuePair("tablet" , "Tablet"), new KeyValuePair("tachometer" , "Tachometer"), new KeyValuePair("tasks" , "Tasks"), new KeyValuePair("thumbs-down" , "Thumbs Down"), new KeyValuePair("thumbs-o-down" , "Thumbs Down"), new KeyValuePair("thumbs-o-up" , "Thumbs Up"), new KeyValuePair("thumbs-up" , "Thumbs Up"), new KeyValuePair("thumb-tack" , "Thumb Tack"), new KeyValuePair("trash-o" , "Trash"), new KeyValuePair("trophy" , "Trophy"), new KeyValuePair("truck" , "Truck"), new KeyValuePair("umbrella" , "Umbrella"), new KeyValuePair("wheelchair" , "Wheelchair"), new KeyValuePair("windows" , "Windows"), new KeyValuePair("wrench" , "Wrench") }.AsReadOnly(); } // Icon Colours if (this._IconColourCache == null) { this._IconColourCache = new List>(){ new KeyValuePair("lime" , "Lime"), new KeyValuePair("green" , "Green"), new KeyValuePair("emerald" , "Emerald"), new KeyValuePair("teal" , "Teal"), new KeyValuePair("cyan" , "Cyan"), new KeyValuePair("cobalt" , "Cobalt"), new KeyValuePair("indigo" , "Indigo"), new KeyValuePair("violet" , "Violet"), new KeyValuePair("pink" , "Pink"), new KeyValuePair("magenta" , "Magenta"), new KeyValuePair("crimson" , "Crimson"), new KeyValuePair("red" , "Red"), new KeyValuePair("orange" , "Orange"), new KeyValuePair("amber" , "Amber"), new KeyValuePair("yellow" , "Yellow"), new KeyValuePair("brown" , "Brown"), new KeyValuePair("olive" , "Olive"), new KeyValuePair("steel" , "Steel"), new KeyValuePair("mauve" , "Mauve"), new KeyValuePair("sienna" , "Sienna") }.AsReadOnly(); } // SLA Options if (this._SlaOptions == null) { this._SlaOptions = new List>() { new KeyValuePair(0, ""), new KeyValuePair(15, "15 minutes"), new KeyValuePair(30, "30 minutes"), new KeyValuePair(60, "1 hour"), new KeyValuePair(60 * 2, "2 hours"), new KeyValuePair(60 * 4, "4 hours"), new KeyValuePair(60 * 8, "8 hours"), new KeyValuePair(60 * 24, "1 day"), new KeyValuePair(60 * 24 * 2, "2 days"), new KeyValuePair(60 * 24 * 3, "3 days"), new KeyValuePair(60 * 24 * 4, "4 days"), new KeyValuePair(60 * 24 * 5, "5 days"), new KeyValuePair(60 * 24 * 6, "6 days"), new KeyValuePair(60 * 24 * 7, "1 week"), new KeyValuePair(60 * 24 * 7 * 2, "2 weeks"), new KeyValuePair(60 * 24 * 7 * 3, "3 weeks"), new KeyValuePair(60 * 24 * 7 * 4, "4 weeks"), new KeyValuePair(60 * 24 * 7 * 4 * 2, "2 months"), new KeyValuePair(60 * 24 * 7 * 4 * 3, "3 months"), new KeyValuePair(60 * 24 * 7 * 4 * 4, "4 months"), new KeyValuePair(60 * 24 * 7 * 4 * 5, "5 months"), new KeyValuePair(60 * 24 * 7 * 4 * 6, "6 months") }.AsReadOnly(); } #endregion } private void CalculateSubjectCache() { _SubjectCache = (from c in _Cache.Values.ToList() from s in c.SubjectIds group c by s into subjectId select subjectId).ToDictionary(g => g.Key.ToLower(), g => g.ToList()); } public ReadOnlyCollection> Icons { get { return this._Icons; } } public ReadOnlyCollection> IconColours { get { return this._IconColourCache; } } public ReadOnlyCollection> SlaOptions { get { return this._SlaOptions; } } public JobQueueToken UpdateQueue(JobQueue JobQueue) { var token = JobQueueToken.FromJobQueue(JobQueue); JobQueueToken existingToken; if (_Cache.TryGetValue(JobQueue.Id, out existingToken)) { if (_Cache.TryUpdate(JobQueue.Id, token, existingToken)) { if (existingToken.JobQueue.SubjectIds != token.JobQueue.SubjectIds) CalculateSubjectCache(); return token; } else return null; } else { if (_Cache.TryAdd(JobQueue.Id, token)) { CalculateSubjectCache(); return token; } else return null; } } public bool RemoveQueue(int JobQueueId) { JobQueueToken token; if (_Cache.TryRemove(JobQueueId, out token)) { CalculateSubjectCache(); return true; } else { return false; } } public JobQueueToken GetQueue(int JobQueueId) { JobQueueToken token; if (_Cache.TryGetValue(JobQueueId, out token)) return token; else return null; } public ReadOnlyCollection GetQueues() { return _Cache.Values.ToList().AsReadOnly(); } private IEnumerable GetQueuesForSubject(string SubjectId) { List tokens; if (_SubjectCache.TryGetValue(SubjectId.ToLower(), out tokens)) return tokens; else return Enumerable.Empty(); } public ReadOnlyCollection GetQueuesForSubject(IEnumerable SubjectIds) { return SubjectIds.SelectMany(sid => GetQueuesForSubject(sid)).Distinct().ToList().AsReadOnly(); } public void ReInitializeCache(DiscoDataContext Database) { Initialize(Database); } } }