/// <summary> /// Sets the app Id /// </summary> /// <param name="appId"></param> public void SetApp(int appId) { if (appId == 0) { throw new ArgumentException(nameof(appId)); } //Check if app exists var bytesAppIds = KeyValueStore.Get(KeyValueStore.DefaultType, KeyGenerator.AppsKey, null); List <int> appIds = null; if (bytesAppIds != null) { appIds = (List <int>)BinarySerializerHelper.DeserializeObject(bytesAppIds); } if (appIds == null || !appIds.Contains(appId)) { throw new ArgumentException($"{nameof(appId)} - doesn't exist"); } AppId = appId; ForkProvider = new ForkProvider <TDataTypesEnum>(KeyValueStore, AppId); }
public T Get <T>(TDataTypesEnum type, string key, object extraParams = null) { var currentFork = Fork; while (currentFork != null) { var byteValue = KeyValueStore.Get(type, KeyGenerator.GenerateForkValueKey(AppId, currentFork.Id, key), extraParams); if (byteValue != null) { if (typeof(T) == typeof(byte[])) { return((T)Convert.ChangeType(byteValue, typeof(T))); } return((T)BinarySerializerHelper.DeserializeObject(byteValue)); } if (KeyValueStore.Exists(type, KeyGenerator.GenerateForkNullKey(AppId, currentFork.Id, key), null)) { return(default(T)); } currentFork = currentFork.Parent; } return(default(T)); }
public List <DTOs.App> GetApps() { var bytesAppIds = KeyValueStore.Get(KeyValueStore.DefaultType, KeyGenerator.AppsKey, null); List <int> appIds = null; if (bytesAppIds == null) { return(new List <DTOs.App>()); } appIds = (List <int>)BinarySerializerHelper.DeserializeObject(bytesAppIds); var res = new List <DTOs.App>(); foreach (var appId in appIds) { var bytesApp = KeyValueStore.Get(KeyValueStore.DefaultType, KeyGenerator.GenerateAppKey(appId), null); if (bytesApp == null) { continue; } var app = ProtoBufSerializerHelper.Deserialize <App>(bytesApp); res.Add(new DTOs.App { Id = app.Id, Name = app.Name, Description = app.Description }); } return(res); }
private void InitForksDict() { var rawForks = new Dictionary <int, ForkRawData>(); var forkIds = (List <int>)BinarySerializerHelper.DeserializeObject(Store.Get(Store.DefaultType, KeyGenerator.GenerateForksKey(AppId), null)); foreach (var forkId in forkIds) { rawForks[forkId] = ProtoBufSerializerHelper.Deserialize <ForkRawData>(Store.Get(Store.DefaultType, KeyGenerator.GenerateForkKey(AppId, forkId), null)); _forksTimeStamps[forkId] = (DateTime)BinarySerializerHelper.DeserializeObject(Store.Get(Store.DefaultType, KeyGenerator.GenerateForkTimeStampKey(AppId, forkId), null)); } var masterForks = rawForks.Where(x => x.Value.ParentId == 0).Select(x => x.Key).ToArray(); foreach (var masterFork in masterForks) { CreateFork(rawForks, masterFork); } }
public void StackExchangeRedisKeyValueStore_String() { var store = new StackExchangeRedisKeyValueStore("localhost:6379"); store.Set(StackExchangeRedisDataTypesEnum.String, "testKey1", BinarySerializerHelper.SerializeObject(123)); var res = (int)BinarySerializerHelper.DeserializeObject(store.Get(StackExchangeRedisDataTypesEnum.String, "testKey1")); Assert.AreEqual(123, res); store.Set(StackExchangeRedisDataTypesEnum.String, new List <Tuple <string, byte[], object> > { Tuple.Create <string, byte[], object>("testKey1_1", BinarySerializerHelper.SerializeObject(1), null), Tuple.Create <string, byte[], object>("testKey1_2", BinarySerializerHelper.SerializeObject(2), null), Tuple.Create <string, byte[], object>("testKey1_3", BinarySerializerHelper.SerializeObject(3), null) }); var multipleRes = store.Get(StackExchangeRedisDataTypesEnum.String, new List <Tuple <string, object> > { Tuple.Create <string, object>("testKey1_1", null), Tuple.Create <string, object>("testKey1_2", null), Tuple.Create <string, object>("testKey1_3", null) }); Assert.AreEqual(1, (int)BinarySerializerHelper.DeserializeObject(multipleRes["testKey1_1"])); Assert.AreEqual(2, (int)BinarySerializerHelper.DeserializeObject(multipleRes["testKey1_2"])); Assert.AreEqual(3, (int)BinarySerializerHelper.DeserializeObject(multipleRes["testKey1_3"])); store.Delete(StackExchangeRedisDataTypesEnum.String, new List <Tuple <string, object> > { Tuple.Create <string, object>("testKey1_1", null), Tuple.Create <string, object>("testKey1_2", null) }); multipleRes = store.Get(StackExchangeRedisDataTypesEnum.String, new List <Tuple <string, object> > { Tuple.Create <string, object>("testKey1_1", null), Tuple.Create <string, object>("testKey1_2", null), Tuple.Create <string, object>("testKey1_3", null) }); Assert.AreEqual(3, (int)BinarySerializerHelper.DeserializeObject(multipleRes["testKey1_3"])); Assert.AreEqual(1, multipleRes.Count); }
/// <summary> /// Creates a new app and a master fork /// On success sets the app id /// </summary> /// <param name="appId"></param> /// <param name="name"></param> /// <param name="description"></param> public void CreateApp(int appId, string name, string description) { var bytesAppIds = KeyValueStore.Get(KeyValueStore.DefaultType, KeyGenerator.AppsKey, null); List <int> appIds = null; if (bytesAppIds != null) { appIds = (List <int>)BinarySerializerHelper.DeserializeObject(bytesAppIds); } else { appIds = new List <int>(); KeyValueStore.Set(KeyValueStore.DefaultType, KeyGenerator.AppsKey, BinarySerializerHelper.SerializeObject(appIds), null); } if (appIds.Contains(appId)) { throw new ArgumentException(nameof(appId)); } appIds.Add(appId); KeyValueStore.Set(KeyValueStore.DefaultType, KeyGenerator.AppsKey, BinarySerializerHelper.SerializeObject(appIds), null); var res = new App { Id = appId, Name = name, Description = description }; KeyValueStore.Set(KeyValueStore.DefaultType, KeyGenerator.GenerateAppKey(appId), ProtoBufSerializerHelper.Serialize(res), null); KeyValueStore.Set(KeyValueStore.DefaultType, KeyGenerator.GenerateForksKey(appId), BinarySerializerHelper.SerializeObject(new List <int>()), null); SetApp(appId); CreateMasterFork(); }
public void StackExchangeRedisKeyValueStore_Hash() { var store = new StackExchangeRedisKeyValueStore("localhost:6379"); store.Set(StackExchangeRedisDataTypesEnum.Hash, "testKey2", BinarySerializerHelper.SerializeObject(123), new StackExchangeRedisHashParams { HashField = "testKey2Hash" }); var res = (int)BinarySerializerHelper.DeserializeObject(store.Get(StackExchangeRedisDataTypesEnum.Hash, "testKey2", new StackExchangeRedisHashParams { HashField = "testKey2Hash" })); Assert.AreEqual(123, res); store.Set(StackExchangeRedisDataTypesEnum.Hash, new List <Tuple <string, byte[], object> > { Tuple.Create <string, byte[], object>("testKey2_1", BinarySerializerHelper.SerializeObject(4), new StackExchangeRedisHashParams { HashField = "testKey2_1_1" }), Tuple.Create <string, byte[], object>("testKey2_1", BinarySerializerHelper.SerializeObject(5), new StackExchangeRedisHashParams { HashField = "testKey2_1_2" }), Tuple.Create <string, byte[], object>("testKey2_1", BinarySerializerHelper.SerializeObject(6), new StackExchangeRedisHashParams { HashField = "testKey2_1_3" }) }); var multipleRes = store.Get(StackExchangeRedisDataTypesEnum.Hash, new List <Tuple <string, object> > { Tuple.Create <string, object>("testKey2_1", new StackExchangeRedisHashParams { HashField = "testKey2_1_1" }), Tuple.Create <string, object>("testKey2_1", new StackExchangeRedisHashParams { HashField = "testKey2_1_2" }), Tuple.Create <string, object>("testKey2_1", new StackExchangeRedisHashParams { HashField = "testKey2_1_3" }) }); Assert.AreEqual(4, (int)BinarySerializerHelper.DeserializeObject(multipleRes["testKey2_1_1"])); Assert.AreEqual(5, (int)BinarySerializerHelper.DeserializeObject(multipleRes["testKey2_1_2"])); Assert.AreEqual(6, (int)BinarySerializerHelper.DeserializeObject(multipleRes["testKey2_1_3"])); store.Delete(StackExchangeRedisDataTypesEnum.Hash, new List <Tuple <string, object> > { Tuple.Create <string, object>("testKey2_1", new StackExchangeRedisHashParams { HashField = "testKey2_1_2" }), Tuple.Create <string, object>("testKey2_1", new StackExchangeRedisHashParams { HashField = "testKey2_1_3" }) }); multipleRes = store.Get(StackExchangeRedisDataTypesEnum.Hash, new List <Tuple <string, object> > { Tuple.Create <string, object>("testKey2_1", new StackExchangeRedisHashParams { HashField = "testKey2_1_1" }), Tuple.Create <string, object>("testKey2_1", new StackExchangeRedisHashParams { HashField = "testKey2_1_2" }), Tuple.Create <string, object>("testKey2_1", new StackExchangeRedisHashParams { HashField = "testKey2_1_3" }) }); Assert.AreEqual(4, (int)BinarySerializerHelper.DeserializeObject(multipleRes["testKey2_1_1"])); Assert.AreEqual(1, multipleRes.Count); store.Delete(StackExchangeRedisDataTypesEnum.Hash, "testKey2_1", null); multipleRes = store.Get(StackExchangeRedisDataTypesEnum.Hash, new List <Tuple <string, object> > { Tuple.Create <string, object>("testKey2_1", new StackExchangeRedisHashParams { HashField = "testKey2_1_1" }), Tuple.Create <string, object>("testKey2_1", new StackExchangeRedisHashParams { HashField = "testKey2_1_2" }), Tuple.Create <string, object>("testKey2_1", new StackExchangeRedisHashParams { HashField = "testKey2_1_3" }) }); Assert.AreEqual(0, multipleRes.Count); }
public IDictionary <string, T> Get <T>(TDataTypesEnum type, IEnumerable <Tuple <string, object> > keys) { var currentFork = Fork; var missingKeys = keys.Select(x => x.Item1).ToList(); // Easy access to tuple data var keysDict = keys.ToDictionary(x => x.Item1, x => x.Item2); var res = new Dictionary <string, T>(); while (currentFork != null) { var keysForGet = new List <Tuple <string, object> >(); var generatedKeyToOriginalKey = new Dictionary <string, string>(); foreach (var key in missingKeys) { var generatedKey = KeyGenerator.GenerateForkValueKey(AppId, currentFork.Id, key); keysForGet.Add(Tuple.Create(generatedKey, keysDict[key])); generatedKeyToOriginalKey[generatedKey] = key; } var byteValues = KeyValueStore.Get(type, keysForGet); if (typeof(T) == typeof(byte[])) { foreach (var key in byteValues.Keys) { res[generatedKeyToOriginalKey[key]] = (T)Convert.ChangeType(byteValues[key], typeof(T)); } } else { foreach (var key in byteValues.Keys) { res[generatedKeyToOriginalKey[key]] = (T)BinarySerializerHelper.DeserializeObject(byteValues[key]); } } missingKeys = missingKeys.Except(byteValues.Keys.Select(x => generatedKeyToOriginalKey[x])).ToList(); var nullMissingKeys = new List <string>(); foreach (var missingKey in missingKeys.ToList()) { if (KeyValueStore.Exists(type, KeyGenerator.GenerateForkNullKey(AppId, currentFork.Id, missingKey), keysDict[missingKey])) { nullMissingKeys.Add(missingKey); } } missingKeys = missingKeys.Except(nullMissingKeys).ToList(); if (missingKeys.Count == 0) { break; } currentFork = currentFork.Parent; } return(res); }
private void UpdateForks() { var changedForkIds = new HashSet <int>(); var updatedForkIds = (List <int>)BinarySerializerHelper.DeserializeObject(Store.Get(Store.DefaultType, KeyGenerator.GenerateForksKey(AppId), null)); var newForkIds = updatedForkIds.Except(_forks.Keys); foreach (var newForkId in newForkIds) { var bytesNewRawFork = Store.Get(Store.DefaultType, KeyGenerator.GenerateForkKey(AppId, newForkId), null); if (bytesNewRawFork == null) { continue; } var newRawFork = ProtoBufSerializerHelper.Deserialize <ForkRawData>(bytesNewRawFork); var bytesNewForkTimeStamp = Store.Get(Store.DefaultType, KeyGenerator.GenerateForkTimeStampKey(AppId, newForkId), null); if (bytesNewForkTimeStamp == null) { continue; } var newForkTimeStamp = (DateTime)BinarySerializerHelper.DeserializeObject(bytesNewForkTimeStamp); var parentFork = newRawFork.ParentId == 0 ? null : _forks[newRawFork.ParentId]; var newFork = new Fork { Id = newForkId, Name = newRawFork.Name, Description = newRawFork.Description, IsInGracePeriod = newRawFork.IsInGracePeriod, Parent = parentFork }; if (parentFork != null) { parentFork.Children.Add(newFork); changedForkIds.Add(parentFork.Id); } _forks[newForkId] = newFork; _forksTimeStamps[newForkId] = newForkTimeStamp; } var toDel = _forks.Keys.Except(updatedForkIds).ToList(); foreach (var toDelFork in toDel) { _forks.Remove(toDelFork); _forksTimeStamps.Remove(toDelFork); } foreach (var forkId in _forks.Keys.ToList()) { var newTimeStamp = (DateTime)BinarySerializerHelper.DeserializeObject(Store.Get(Store.DefaultType, KeyGenerator.GenerateForkTimeStampKey(AppId, forkId), null)); var _currentForkTimeStamp = _forksTimeStamps[forkId]; if (newTimeStamp > _currentForkTimeStamp) { var rawFork = ProtoBufSerializerHelper.Deserialize <ForkRawData>(Store.Get(Store.DefaultType, KeyGenerator.GenerateForkKey(AppId, forkId), null)); _forksTimeStamps[forkId] = newTimeStamp; UpdateFork(_forks[forkId], rawFork); changedForkIds.Add(forkId); } } RaiseForkChanged(changedForkIds.ToList()); }
private List <int> GetForkIds() { return((List <int>)BinarySerializerHelper.DeserializeObject(KeyValueStore.Get(KeyValueStore.DefaultType, KeyGenerator.GenerateForksKey(AppId), null))); }
/// <summary> /// Merge all the keys from one fork to another fork, a new fork is created from the target with the new data /// </summary> /// <param name="originForkId">Origin fork id</param> /// <param name="targetForkId">Target fork id</param> /// <returns>New fork id, Target fork id is the parent</returns> public int MergeFork(int originForkId, int targetForkId) { var usedKeys = new HashSet <string>(); var valuesToSet = new List <Tuple <string, TDataTypesEnum, byte[], object> >(); var keysToDelete = new Dictionary <string, TDataTypesEnum>(); var currentFork = ForkProvider.GetFork(originForkId); var targetFork = ForkProvider.GetFork(targetForkId); while (!IsCommonParent(currentFork, targetFork)) { if (currentFork == null) { throw new ArgumentException($"No common parents between {originForkId} and {targetForkId}"); } var forkPattern = KeyGenerator.GenerateForkValuePattern(AppId, currentFork.Id); var keys = KeyValueStore.Keys($"{forkPattern}*"); foreach (var key in keys) { var originalKey = key.Substring(forkPattern.Length); // If the key was used/deleted in a lower fork, this key is not relevant if (usedKeys.Contains(originalKey) || keysToDelete.ContainsKey(originalKey)) { continue; } if (originalKey.EndsWith(KeyGenerator.NullKeyPostFix)) { var type = (TDataTypesEnum)BinarySerializerHelper.DeserializeObject(KeyValueStore.Get(KeyValueStore.DefaultType, key, null)); keysToDelete.Add(originalKey.Substring(0, originalKey.Length - KeyGenerator.NullKeyPostFix.Length), type); } else { var keyDataCollection = KeyValueStore.GetKeyData(key); foreach (var keyData in keyDataCollection) { valuesToSet.Add(Tuple.Create(originalKey, keyData.Item1, keyData.Item2, keyData.Item3)); } usedKeys.Add(originalKey); } } currentFork = currentFork.Parent; } var newForkId = CreateFork($"{targetFork.Name} Merge", "", targetFork.Id); var wrapper = GetWrapper(newForkId); foreach (var keyToDelete in keysToDelete) { wrapper.Delete(keyToDelete.Value, keyToDelete.Key); } foreach (var value in valuesToSet) { wrapper.Set(value.Item2, value.Item1, value.Item3, value.Item4); } return(newForkId); }