Skip to content

Commit

Permalink
unified the memoization stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
Hannes Georg committed Jun 19, 2013
1 parent be7824f commit 5a1b7fe
Show file tree
Hide file tree
Showing 19 changed files with 299 additions and 89 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ TODO ( loosely by priority )
- Feature: Ref#update(:reckless)
- Efficiency: efficient Ref#resolve+update
- Feature: Remotes/Clone/Push/Fetch ( blocked by config )
- Code Quality: Unify memoizing
- Awesomeness: benchmark backends against each other
- Feature: Index/Working Directory
- Feature: RefWalks
Expand Down
20 changes: 8 additions & 12 deletions lib/multi_git/directory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ def walk_leaves(&block)
child.walk(:leaves,&block)
end
end

def entries
Hash[
object.map{|entry| [entry.name, entry.with_parent(self) ] }
]
end
end

class Builder < TreeEntry::Builder
Expand All @@ -68,22 +74,12 @@ def make_inner(*args)
def entry_set(key, value)
object.entry_set(key, make_entry(key, value))
end

def entries
Hash[
object.map{|entry| [entry.name, entry.with_parent(self) ] }
]
end

end

include Base
extend Utils::Memoizes

def entries
@entries ||= Hash[
object.map{|entry| [entry.name, entry.with_parent(self) ] }
]
end
memoize :entries

end

Expand Down
43 changes: 25 additions & 18 deletions lib/multi_git/git_backend/commit.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
require 'multi_git/git_backend/object'
require 'multi_git/commit'
require 'monitor'
module MultiGit
module GitBackend
class Commit < Object
include MultiGit::Commit
include MonitorMixin

def parents
read!
@parents ||= @parent_oids.map{|oid| repository.read(oid) }
@parent_oids.map{|oid| repository.read(oid) }
end

def tree
read!
@tree ||= repository.read(@tree_oid)
repository.read(@tree_oid)
end

memoize :parents, :tree

def message
read!
@message
Expand All @@ -40,28 +44,31 @@ def commit_time
@commit_time
end

private

def read!
return if @read
@read = true
@header, @message = content.split("\n\n")
@parent_oids = []
@header.each_line do |line|
type, content = line.split(' ',2)
case(type)
when 'tree' then @tree_oid = content.chomp
when 'parent' then @parent_oids << content.chomp
when 'author' then
@author, @time = parse_signature(content)
when 'committer' then
@committer, @commit_time = parse_signature(content)
else
raise "Commit line type: #{type}"
synchronize do
return if @read
@read = true
@header, @message = content.split("\n\n")
@parent_oids = []
@header.each_line do |line|
type, content = line.split(' ',2)
case(type)
when 'tree' then @tree_oid = content.chomp
when 'parent' then @parent_oids << content.chomp
when 'author' then
@author, @time = parse_signature(content)
when 'committer' then
@committer, @commit_time = parse_signature(content)
else
raise "Commit line type: #{type}"
end
end
end
end

private

SIGNATURE_RX = /\A(.+) <([^>]+)> (\d+) ([\-+]\d{2})(\d{2})\Z/

def parse_signature(content)
Expand Down
21 changes: 13 additions & 8 deletions lib/multi_git/git_backend/object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,35 @@
class MultiGit::GitBackend::Object

extend Forwardable
extend MultiGit::Utils::Memoizes

include MultiGit::Object

def initialize(repository, oid, content = nil)
@repository = repository
@git = repository.__backend__
@oid = oid
@content = content ? content.dup.freeze : nil
if content
set_memoized_content( content.dup.freeze )
end
end

def bytesize
@size ||= begin
if @content
@content.bytesize
else
@git['cat-file',:s,@oid].to_i
end
if @content
@content.bytesize
else
@git['cat-file',:s,@oid].to_i
end
end

memoize :bytesize

def content
@content ||= @git['cat-file',type.to_s,@oid].freeze
@git['cat-file',type.to_s,@oid].freeze
end

memoize :content

def to_io
StringIO.new(content)
end
Expand Down
6 changes: 5 additions & 1 deletion lib/multi_git/git_backend/repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ def __backend__

Utils = MultiGit::Utils

extend Utils::Memoizes

OBJECT_CLASSES = {
:blob => Blob,
:tree => Tree,
Expand Down Expand Up @@ -133,9 +135,11 @@ def ref(name)
end

def config
@config ||= Config.new(@git)
Config.new(@git)
end

memoize :config

def remote( name_or_url )
if looks_like_remote_url? name_or_url
remote = Remote.new(self, name_or_url)
Expand Down
13 changes: 7 additions & 6 deletions lib/multi_git/git_backend/tree.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@ class Tree < Object
LS_TREE_REGEX = /^([0-7]{6}) (?:blob|tree|commit) (\h{40})\t(.+)$/

include MultiGit::Tree
extend MultiGit::Utils::Memoizes

def raw_entries
@raw_entries ||= begin
@git.call('ls-tree', oid) do |stdout|
stdout.each_line.map do |line|
raise unless LS_TREE_REGEX =~ line
[$3,$1.to_i(8),$2]
end
@git.call('ls-tree', oid) do |stdout|
stdout.each_line.map do |line|
raise unless LS_TREE_REGEX =~ line
[$3,$1.to_i(8),$2]
end
end
end

memoize :raw_entries

end
end
21 changes: 13 additions & 8 deletions lib/multi_git/jgit_backend/commit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,43 @@ class Commit < Object
import 'org.eclipse.jgit.revwalk.RevWalk'

def parents
@parents ||= java_commit.parents.map{|pr| repository.read(pr.getId()) }
java_commit.parents.map{|pr| repository.read(pr.getId()) }
end

def tree
@tree ||= repository.read(java_commit.tree.id)
repository.read(java_commit.tree.id)
end

def message
@message ||= java_commit.full_message.freeze
java_commit.full_message.freeze
end

def time
@time ||= java_commit.author_ident.when
java_commit.author_ident.when
end

def commit_time
@time ||= java_commit.committer_ident.when
java_commit.committer_ident.when
end

def author
@author ||= MultiGit::Handle.new(java_commit.author_ident.name,java_commit.author_ident.email_address)
MultiGit::Handle.new(java_commit.author_ident.name,java_commit.author_ident.email_address)
end

def committer
@committer ||= MultiGit::Handle.new(java_commit.committer_ident.name,java_commit.committer_ident.email_address)
MultiGit::Handle.new(java_commit.committer_ident.name,java_commit.committer_ident.email_address)
end

memoize :parents, :tree, :message, :time, :commit_time, :author, :committer

private

def java_commit
@java_commit ||= repository.use_reader{|rd| RevWalk.new(rd).parseCommit(java_oid) }
repository.use_reader{|rd| RevWalk.new(rd).parseCommit(java_oid) }
end

memoize :java_commit

end
end
end
11 changes: 8 additions & 3 deletions lib/multi_git/jgit_backend/object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class MultiGit::JGitBackend::Object
import "org.eclipse.jgit.lib.ObjectId"

extend Forwardable
extend MultiGit::Utils::Memoizes

include MultiGit::Object

Expand All @@ -14,7 +15,7 @@ def initialize(repository,oid, object = nil)
@java_oid = oid
@git = repository.__backend__
@oid = ObjectId.toString(oid)
@java_object = object
set_memoized_java_object( object ) if object
end

def bytesize
Expand All @@ -26,9 +27,11 @@ def to_io
end

def content
@content ||= to_io.read.freeze
to_io.read.freeze
end

memoize :content

private

def java_stream
Expand All @@ -42,7 +45,9 @@ def java_stream
attr :java_oid

def java_object
@java_object ||= repository.use_reader{|rdr| rdr.open(@java_oid) }
repository.use_reader{|rdr| rdr.open(@java_oid) }
end

memoize :java_object

end
15 changes: 8 additions & 7 deletions lib/multi_git/jgit_backend/ref.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module JGitBackend
class Ref

include MultiGit::Ref
extend Utils::Memoizes

# HACK!
# @api private
Expand Down Expand Up @@ -97,15 +98,15 @@ def initialize(repository, name)

def target
return nil unless java_ref
@target ||= begin
if java_ref.symbolic?
repository.ref(java_ref.target.name)
else
repository.read(java_ref.getObjectId())
end
end
if java_ref.symbolic?
repository.ref(java_ref.target.name)
else
repository.read(java_ref.getObjectId())
end
end

memoize :target

# @api private
# @visibility private
attr :java_ref
Expand Down
5 changes: 4 additions & 1 deletion lib/multi_git/jgit_backend/repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module MultiGit::JGitBackend
class Repository < MultiGit::Repository

extend Forwardable
extend MultiGit::Utils::Memoizes

private
OBJECT_CLASSES = {
Expand Down Expand Up @@ -117,9 +118,11 @@ def ref(name)
end

def config
@config ||= Config.new(@git.config)
Config.new(@git.config)
end

memoize :config

private
ALL_FILTER = %r{\Arefs/(?:heads|remotes)}
LOCAL_FILTER = %r{\Arefs/heads}
Expand Down
6 changes: 4 additions & 2 deletions lib/multi_git/rugged_backend/commit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ class Commit < Object
include MultiGit::Commit

def tree
@tree ||= repository.read(rugged_object.tree_oid)
repository.read(rugged_object.tree_oid)
end

def parents
@parents ||= rugged_object.parent_oids.map{|oid| repository.read(oid) }
rugged_object.parent_oids.map{|oid| repository.read(oid) }
end

memoize :tree, :parents

def author
MultiGit::Handle.new(rugged_object.author[:name],rugged_object.author[:email])
end
Expand Down
Loading

0 comments on commit 5a1b7fe

Please sign in to comment.