# File lib/gibbler/aliases.rb, line 24 def commit; gibbler_commit; end
# File lib/gibbler/aliases.rb, line 30 def find_long(*args, &b); gibbler_find_long(*args, &b); end
Stores a clone of the current object instance using the current digest value. If the object was not changed, this method does nothing but return the gibble.
NOTE: This method is not fully thread safe. It uses a Mutex.synchronize but there's a race condition where two threads can attempt to commit at near the same time. The first will get the lock and create the commit. The second will get the lock and create another commit immediately after. What we probably want is for the second thread to return the digest for that first snapshot, but how do we know this was a result of the race conditioon rather than two legitimate calls for a snapshot?
# File lib/gibbler/history.rb, line 71 def gibbler_commit now, digest, point = nil,nil,nil if self.__gibbler_history.nil? @@mutex.synchronize { self.__gibbler_history ||= { :history => [], :objects => {}, :stamp => {} } } end @@mutex.synchronize { now, digest, point = ::Time.now, self.gibbler, self.clone self.__gibbler_history[:history] << digest self.__gibbler_history[:stamp][digest] = now self.__gibbler_history[:objects][digest] = point } digest end
Returns the long digest associated to the short digest g. If g is longer than 8 characters it returns the value of g.
# File lib/gibbler/history.rb, line 140 def gibbler_find_long(g) return if g.nil? return g if g.size > 8 gibbler_history.select { |d| d.match /\A#{g}/ }.first end
Returns an Array of digests in the order they were committed. If short is anything but false, the digests will be converted to the short 8 character digests.
# File lib/gibbler/history.rb, line 27 def gibbler_history(short=false) # Only a single thread should attempt to initialize the store. if self.__gibbler_history.nil? @@mutex.synchronize { self.__gibbler_history ||= { :history => [], :objects => {}, :stamp => {} } } end if short == false self.__gibbler_history[:history] else self.__gibbler_history[:history].collect { |g| g.short } end end
Does the current object have any history?
# File lib/gibbler/history.rb, line 134 def gibbler_history? !gibbler_history.empty? end
Returns the object stored under the given digest g. If g is not a valid digest, returns nil.
# File lib/gibbler/history.rb, line 43 def gibbler_object(g=nil) g = gibbler_find_long g g = self.gibbler_history.last if g.nil? return unless gibbler_valid? g self.__gibbler_history[:objects][ g ] end
Revert this object to a previously known state. If called without arguments it will revert to the most recent commit. If a digest is specified g, it will revert to that point.
Ruby does not support replacing self (self = previous_self) so each object type needs to implement its own __gibbler_revert! method. This default run some common checks and then defers to self.__gibbler_revert!.
Raise the following exceptions:
NoRevert: if this object doesn't have a __gibbler_revert! method
NoHistory: This object has no commits
BadDigest: The given digest is not in the history for this object
If g matches the current digest value this method does nothing.
Returns the new digest (g).
# File lib/gibbler/history.rb, line 106 def gibbler_revert!(g=nil) raise NoRevert unless self.respond_to? :__gibbler_revert! raise NoHistory, self.class unless gibbler_history? raise BadDigest, g if !g.nil? && !gibbler_valid?(g) g = self.gibbler_history.last if g.nil? g = gibbler_find_long g # Do nothing if the given digest matches the current gibble. # NOTE: We use __gibbler b/c it doesn't update self.gibbler_cache. unless self.__gibbler == g @@mutex.synchronize { # Always make sure self.gibbler_digest is a Gibbler::Digest self.gibbler_cache = g.is_a?(Gibbler::Digest) ? g : Gibbler::Digest.new(g) self.__gibbler_revert! } end self.gibbler_cache end
Returns the timestamp (a Time object) when the digest g was committed. If g is not a valid gibble, returns nil.
# File lib/gibbler/history.rb, line 53 def gibbler_stamp(g=nil) g = gibbler_find_long g g = self.gibbler_history.last if g.nil? return unless gibbler_valid? g self.__gibbler_history[:stamp][ g ] end
Is the given digest g contained in the history for this object?
# File lib/gibbler/history.rb, line 128 def gibbler_valid?(g) return false unless gibbler_history? gibbler_history.member? gibbler_find_long(g) end
# File lib/gibbler/aliases.rb, line 23 def history(*args, &b); gibbler_history(*args, &b); end
# File lib/gibbler/aliases.rb, line 28 def history?; gibbler_history?; end
# File lib/gibbler/aliases.rb, line 25 def object(*args, &b); gibbler_object(*args, &b); end
# File lib/gibbler/aliases.rb, line 27 def revert!(*args, &b); gibbler_revert!(*args, &b); end
Generated with the Darkfish Rdoc Generator 2.