private ObjectStoreEntry readFile(string fname, ISerializer serializer, DateTime now, ref long priorLoadSize, Stopwatch clock) { using (var fs = new FileStream(fname, FileMode.Open))//, FileAccess.Read, FileShare.Read, 64*1024, FileOptions.SequentialScan)) { var entry = new ObjectStoreEntry(); try { entry.Value = serializer.Deserialize(fs); } catch (Exception error) { WriteLog(MessageType.Error, FROM, "Deserialization error in file '{0}': {1}".Args(fname, error.Message)); return(null); } Interlocked.Add(ref m_LoadSize, fs.Length); if (m_LoadSize - priorLoadSize > 32 * 1024 * 1024) { WriteLog(MessageType.Info, FROM, "Loaded disk bytes {0} in {1}".Args(LoadSize, clock.Elapsed)); priorLoadSize = m_LoadSize; } entry.Key = getGUIDFromFileName(fname); entry.LastTime = now; entry.Status = ObjectStoreEntryStatus.Normal; return(entry); } }
public override void Write(ObjectStoreEntry entry) { using (var fs = new FileStream(getFileName(entry), FileMode.Create)) { m_Serializer.Serialize(fs, entry.Value); } }
/// <summary> /// Puts an object reference "value" into store identified by the "oldKey" under the "newKey". /// If oldKey was not checked in, then checks-in under new key as normally would /// </summary> public void CheckInUnderNewKey(Guid oldKey, Guid newKey, object value, int msTimeout = 0) { if (Status != DaemonStatus.Active) { return; } if (value == null) { Delete(oldKey); return; } var bucket = getBucket(oldKey); ObjectStoreEntry entry = null; lock (bucket) if (!bucket.TryGetValue(oldKey, out entry)) { entry = null; } if (entry != null) { lock (entry) { entry.Value = null; entry.Status = ObjectStoreEntryStatus.Deleted; entry.LastTime = App.LocalizedTime; } } CheckIn(newKey, value, msTimeout); }
/// <summary> /// Deletes object identified by key. Returns true when object was found and marked for deletion /// </summary> public bool Delete(Guid key) { if (Status != DaemonStatus.Active) { return(false); } var bucket = getBucket(key); ObjectStoreEntry entry = null; lock (bucket) if (!bucket.TryGetValue(key, out entry)) { return(false); } lock (entry) { if (entry.Status == ObjectStoreEntryStatus.Deleted) { return(false); } entry.Status = ObjectStoreEntryStatus.Deleted; entry.LastTime = App.LocalizedTime; } return(true); }
/// <summary> /// Retrieves an object reference from the store identified by the "key" or returns null if such object does not exist. /// Object is not going to be persisted until it is checked back in the store using the same number of calls to CheckIn() for the same GUID. /// </summary> public object CheckOut(Guid key) { if (this.Status != DaemonStatus.Active) { return(null); } var bucket = getBucket(key); ObjectStoreEntry entry = null; lock (bucket) if (!bucket.TryGetValue(key, out entry)) { return(null); } lock (entry) { if (entry.Status == ObjectStoreEntryStatus.Deleted) { return(null); } entry.Status = ObjectStoreEntryStatus.CheckedOut; entry.CheckoutCount++; entry.LastTime = App.LocalizedTime; return(entry.Value); } }
/// <summary> /// Retrieves an object reference from the store identified by the "key" or returns null if such object does not exist. /// Object is not going to be persisted as this method provides logical read-only access. If touch=true then object timestamp is updated /// </summary> public object Fetch(Guid key, bool touch = false) { if (this.Status != DaemonStatus.Active) { return(null); } var bucket = getBucket(key); ObjectStoreEntry entry = null; lock (bucket) if (!bucket.TryGetValue(key, out entry)) { return(null); } lock (entry) { if (entry.Status == ObjectStoreEntryStatus.Deleted) { return(null); } if (touch) { entry.LastTime = App.LocalizedTime; } return(entry.Value); } }
/// <summary> /// Puts an object reference "value" into store identified by the "key". /// The object is written in the provider when call count to this method equals to CheckOut() /// </summary> public void CheckIn(Guid key, object value, int msTimeout = 0) { if (Status != DaemonStatus.Active) { return; } if (value == null) { Delete(key); return; } var bucket = getBucket(key); ObjectStoreEntry entry = null; bool isnew = false; lock (bucket) { if (!bucket.TryGetValue(key, out entry)) { isnew = true; entry = new ObjectStoreEntry(); entry.Key = key; entry.Status = ObjectStoreEntryStatus.ChekedIn; entry.LastTime = App.LocalizedTime; entry.MsTimeout = msTimeout; entry.Value = value; bucket.Add(key, entry); } } if (!isnew) { lock (entry) { if (entry.Status == ObjectStoreEntryStatus.Deleted) { return; } if (entry.CheckoutCount > 0) { entry.CheckoutCount--; } if (entry.CheckoutCount == 0) { entry.Status = ObjectStoreEntryStatus.ChekedIn; } entry.LastTime = App.LocalizedTime; entry.MsTimeout = msTimeout; entry.Value = value; } } }
// storePath: c:\root // Guid: facaca23423434dada // -> // c:\root\fa\ca\ca23423434dada.faca private string getFileName(ObjectStoreEntry entry) { var key = entry.Key.ToString(); var path = Path.Combine(getStorePath(), key.Substring(0, 2), key.Substring(2, 2)); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } return(Path.Combine(path, key.Substring(4) + '.' + key.Substring(0, 4)));//for better file system tree balancing, first 4 chars moved as extension to the back }
/// <summary> /// Puts an object back into store identified by the "key". /// The object is written in the provider when call count to this method equals to CheckOut(). /// Returns true if object with such id exists and was checked-in /// </summary> public bool CheckIn(Guid key, int msTimeout = 0) { if (Status != DaemonStatus.Active) { return(false); } var bucket = getBucket(key); ObjectStoreEntry entry = null; lock (bucket) if (!bucket.TryGetValue(key, out entry)) { return(false); } lock (entry) { if (entry.Status == ObjectStoreEntryStatus.Deleted) { return(false); } if (entry.CheckoutCount > 0) { entry.CheckoutCount--; if (entry.CheckoutCount == 0) { entry.Status = ObjectStoreEntryStatus.ChekedIn; } } entry.LastTime = App.LocalizedTime; entry.MsTimeout = msTimeout; } return(true); }
/// <summary> /// Reverts object state to Normal after the call to Checkout. This way the changes (if any) are not going to be persisted. /// Returns true if object was found and checkout canceled. Keep in mind: this method CAN NOT revert inner object state /// to its original state if it was changed, it only unmarks object as changed. /// This method is reentrant just like the Checkout is /// </summary> public bool UndoCheckout(Guid key) { if (this.Status != DaemonStatus.Active) { return(false); } var bucket = getBucket(key); ObjectStoreEntry entry = null; lock (bucket) if (!bucket.TryGetValue(key, out entry)) { return(false); } lock (entry) { if (entry.Status == ObjectStoreEntryStatus.Deleted) { return(false); } if (entry.CheckoutCount > 0) { entry.CheckoutCount--; } if (entry.CheckoutCount == 0) { entry.Status = ObjectStoreEntryStatus.Normal; } return(true); } }
public override void Delete(ObjectStoreEntry entry) { }
public override void Write(ObjectStoreEntry entry) { }
public override void Delete(ObjectStoreEntry entry) { File.Delete(getFileName(entry)); }
public abstract void Delete(ObjectStoreEntry entry);
public abstract void Write(ObjectStoreEntry entry);