Class: Index

Inherits:
Object
  • Object
show all
Defined in:
lib/index.rb,
lib/index/entry.rb,
lib/index/checksum.rb

Defined Under Namespace

Classes: Checksum, Entry

Constant Summary collapse

Invalid =
Class.new(StandardError)
HEADER_SIZE =
12
HEADER_FORMAT =
"a4N2"
SIGNATURE =
"DIRC"
VERSION =
2
ENTRY_FORMAT =
"N10H40nZ*"
ENTRY_BLOCK =
8
ENTRY_MIN_SIZE =
64
REGULAR_MODE =
0100644
EXECUTABLE_MODE =
0100755
MAX_PATH_SIZE =
0xfff

Instance Method Summary collapse

Constructor Details

#initialize(pathname) ⇒ Index

Returns a new instance of Index.



15
16
17
18
19
# File 'lib/index.rb', line 15

def initialize(pathname)
  @pathname = pathname
  @lockfile = Lockfile.new(pathname)
  clear
end

Instance Method Details

#add(pathname, oid, stat) ⇒ Object



64
65
66
67
68
69
70
71
# File 'lib/index.rb', line 64

def add(pathname, oid, stat)
  (1..3).each { |stage| remove_entry_with_stage(pathname, stage) }

  entry = Entry.create(pathname, oid, stat)
  discard_conflicts(entry)
  store_entry(entry)
  @changed = true
end

#add_conflict_set(pathname, items) ⇒ Object



78
79
80
81
82
83
84
85
86
87
# File 'lib/index.rb', line 78

def add_conflict_set(pathname, items)
  remove_entry_with_stage(pathname, 0)

  items.each_with_index do |item, n|
    next unless item
    entry = Entry.create_from_db(pathname, item, n + 1)
    store_entry(entry)
  end
  @changed = true
end

#add_from_db(pathname, item) ⇒ Object



73
74
75
76
# File 'lib/index.rb', line 73

def add_from_db(pathname, item)
  store_entry(Entry.create_from_db(pathname, item, 0))
  @changed = true
end

#child_paths(path) ⇒ Object



122
123
124
# File 'lib/index.rb', line 122

def child_paths(path)
  @parents[path.to_s].to_a
end

#clear!Object



21
22
23
24
# File 'lib/index.rb', line 21

def clear!
  clear
  @changed = true
end

#conflict?Boolean

Returns:

  • (Boolean)


108
109
110
# File 'lib/index.rb', line 108

def conflict?
  @entries.any? { |key, entry| entry.stage > 0 }
end

#conflict_pathsObject



112
113
114
115
116
# File 'lib/index.rb', line 112

def conflict_paths
  paths = Set.new
  each_entry { |entry| paths.add(entry.path) unless entry.stage == 0 }
  paths
end

#each_entryObject



100
101
102
103
104
105
106
# File 'lib/index.rb', line 100

def each_entry
  if block_given?
    @keys.each { |key| yield @entries[key] }
  else
    enum_for(:each_entry)
  end
end

#entry_for_path(path, stage = 0) ⇒ Object



118
119
120
# File 'lib/index.rb', line 118

def entry_for_path(path, stage = 0)
  @entries[[path.to_s, stage]]
end

#loadObject



31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/index.rb', line 31

def load
  clear
  file = open_index_file

  if file
    reader = Checksum.new(file)
    count = read_header(reader)
    read_entries(reader, count)
    reader.verify_checksum
  end
ensure
  file&.close
end

#load_for_updateObject



26
27
28
29
# File 'lib/index.rb', line 26

def load_for_update
  @lockfile.hold_for_update
  load
end

#release_lockObject



60
61
62
# File 'lib/index.rb', line 60

def release_lock
  @lockfile.rollback
end

#remove(pathname) ⇒ Object



94
95
96
97
98
# File 'lib/index.rb', line 94

def remove(pathname)
  remove_entry(pathname)
  remove_children(pathname.to_s)
  @changed = true
end

#tracked?(path) ⇒ Boolean

Returns:

  • (Boolean)


134
135
136
# File 'lib/index.rb', line 134

def tracked?(path)
  tracked_file?(path) or tracked_directory?(path)
end

#tracked_directory?(path) ⇒ Boolean

Returns:

  • (Boolean)


130
131
132
# File 'lib/index.rb', line 130

def tracked_directory?(path)
  @parents.has_key?(path.to_s)
end

#tracked_file?(path) ⇒ Boolean

Returns:

  • (Boolean)


126
127
128
# File 'lib/index.rb', line 126

def tracked_file?(path)
  (0..3).any? { |stage| @entries.has_key?([path.to_s, stage]) }
end

#update_entry_stat(entry, stat) ⇒ Object



89
90
91
92
# File 'lib/index.rb', line 89

def update_entry_stat(entry, stat)
  entry.update_stat(stat)
  @changed = true
end

#write_updatesObject



45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/index.rb', line 45

def write_updates
  return @lockfile.rollback unless @changed

  writer = Checksum.new(@lockfile)

  header = [SIGNATURE, VERSION, @entries.size].pack(HEADER_FORMAT)
  writer.write(header)
  each_entry { |entry| writer.write(entry.to_s) }

  writer.write_checksum
  @lockfile.commit

  @changed = false
end