AddEntries adds the entries to the log. If there are entries in the log with the same index they will be overwritten and the entries after that zeroed out from the log.
(entries []raftpb.Entry)
| 132 | // AddEntries adds the entries to the log. If there are entries in the log with the same index |
| 133 | // they will be overwritten and the entries after that zeroed out from the log. |
| 134 | func (l *wal) AddEntries(entries []raftpb.Entry) error { |
| 135 | if len(entries) == 0 { |
| 136 | return nil |
| 137 | } |
| 138 | // glog.Infof("AddEntries: %+v\n", entries) |
| 139 | fidx, eidx := l.slotGe(entries[0].Index) |
| 140 | |
| 141 | // The first entry in the input is already in the log. We must remove the existing entry |
| 142 | // and all the entries after from the log. |
| 143 | if eidx >= 0 { |
| 144 | if fidx == -1 { |
| 145 | // The existing entry was found in the current file. We only have to zero out |
| 146 | // from the entries after the one in which the entry was found. |
| 147 | if l.nextEntryIdx > eidx { |
| 148 | z.ZeroOut(l.current.Data, entrySize*eidx, entrySize*l.nextEntryIdx) |
| 149 | } |
| 150 | } else { |
| 151 | // The existing entry was found in one of the previous file. |
| 152 | // The logic must do the following. |
| 153 | // 1. Delete all the files after the one in which the entry was found. |
| 154 | // 2. Zero out all the entries after the slot in which the entry was found |
| 155 | // in the file in which it was found. |
| 156 | // 3. Update the pointer to the current file and the list of previous files. |
| 157 | x.AssertTrue(fidx < len(l.files)) |
| 158 | extra := l.files[fidx+1:] |
| 159 | extra = append(extra, l.current) |
| 160 | l.current = l.files[fidx] |
| 161 | |
| 162 | for _, ef := range extra { |
| 163 | glog.V(2).Infof("Deleting extra file: %d\n", ef.fid) |
| 164 | if err := ef.delete(); err != nil { |
| 165 | glog.Errorf("deleting file: %s. error: %v\n", ef.Fd.Name(), err) |
| 166 | } |
| 167 | } |
| 168 | z.ZeroOut(l.current.Data, entrySize*eidx, logFileOffset) |
| 169 | l.files = l.files[:fidx] |
| 170 | } |
| 171 | l.nextEntryIdx = eidx |
| 172 | } |
| 173 | |
| 174 | // Look at the previous entry to find the right offset at which to start writing the value of |
| 175 | // the Data field for each entry. |
| 176 | prev := l.nextEntryIdx - 1 |
| 177 | var offset int |
| 178 | if prev >= 0 { |
| 179 | // There was a previous entry. Retrieve the offset and the size data from that entry to |
| 180 | // calculate the next offset. |
| 181 | e := l.current.getEntry(prev) |
| 182 | offset = int(e.DataOffset()) |
| 183 | offset += sliceSize(l.current.Data, offset) |
| 184 | } else { |
| 185 | // At the start of the file so use entryFileOffset. |
| 186 | offset = logFileOffset |
| 187 | } |
| 188 | |
| 189 | for _, re := range entries { |
| 190 | // Write upto maxNumEntries or 1GB, whatever happens first. |
| 191 | if l.nextEntryIdx >= maxNumEntries || offset+4+len(re.Data) > 1<<30 { |