74 lines
1.2 KiB
Go
74 lines
1.2 KiB
Go
package code
|
|
|
|
const journalLimit = 512
|
|
|
|
type edit struct {
|
|
rev uint64
|
|
off int
|
|
n int
|
|
ins int
|
|
}
|
|
|
|
func (d *Doc) journal(off, n, ins int) {
|
|
d.log = append(d.log, edit{rev: d.rev, off: off, n: n, ins: ins})
|
|
if over := len(d.log) - journalLimit; over > 0 {
|
|
d.log = append(d.log[:0], d.log[over:]...)
|
|
}
|
|
}
|
|
|
|
func (d *Doc) covers(rev uint64) bool {
|
|
return rev <= d.rev && d.rev-rev <= uint64(len(d.log))
|
|
}
|
|
|
|
func (d *Doc) MapSpan(from uint64, s, e int) (int, int, bool) {
|
|
if from == d.rev {
|
|
return s, e, true
|
|
}
|
|
if !d.covers(from) {
|
|
return 0, 0, false
|
|
}
|
|
for _, x := range d.log {
|
|
if x.rev <= from {
|
|
continue
|
|
}
|
|
switch hi := x.off + x.n; {
|
|
case hi <= s:
|
|
delta := x.ins - x.n
|
|
s += delta
|
|
e += delta
|
|
case x.off >= e:
|
|
default:
|
|
return 0, 0, false
|
|
}
|
|
}
|
|
return s, e, true
|
|
}
|
|
|
|
func (d *Doc) Map(from uint64, off int) (int, bool) {
|
|
s, _, ok := d.MapSpan(from, off, off)
|
|
return s, ok
|
|
}
|
|
|
|
func (d *Doc) Unmap(to uint64, off int) (int, bool) {
|
|
if to == d.rev {
|
|
return off, true
|
|
}
|
|
if !d.covers(to) {
|
|
return 0, false
|
|
}
|
|
for i := len(d.log) - 1; i >= 0; i-- {
|
|
x := d.log[i]
|
|
if x.rev <= to {
|
|
break
|
|
}
|
|
switch {
|
|
case off < x.off:
|
|
case off >= x.off+x.ins:
|
|
off += x.n - x.ins
|
|
default:
|
|
return 0, false
|
|
}
|
|
}
|
|
return off, true
|
|
}
|