Commit 3a986436 authored by Igor Drozdov's avatar Igor Drozdov

Cache hovers offsets in a file instead of a hash

Storing them in a hash consumes a lot of RAM
Introducing a file helps to reduce RAM consumption significantly
parent d21d6679
...@@ -7,13 +7,13 @@ import ( ...@@ -7,13 +7,13 @@ import (
) )
type Offset struct { type Offset struct {
At int At int32
Len int Len int32
} }
type Hovers struct { type Hovers struct {
Offsets map[Id]*Offset
File *os.File File *os.File
Offsets *cache
CurrentOffset int CurrentOffset int
} }
...@@ -42,9 +42,14 @@ func NewHovers(tempDir string) (*Hovers, error) { ...@@ -42,9 +42,14 @@ func NewHovers(tempDir string) (*Hovers, error) {
return nil, err return nil, err
} }
offsets, err := newCache(tempDir, "hovers-indexes", Offset{})
if err != nil {
return nil, err
}
return &Hovers{ return &Hovers{
Offsets: make(map[Id]*Offset),
File: file, File: file,
Offsets: offsets,
CurrentOffset: 0, CurrentOffset: 0,
}, nil }, nil
} }
...@@ -69,8 +74,8 @@ func (h *Hovers) Read(label string, line []byte) error { ...@@ -69,8 +74,8 @@ func (h *Hovers) Read(label string, line []byte) error {
} }
func (h *Hovers) For(refId Id) json.RawMessage { func (h *Hovers) For(refId Id) json.RawMessage {
offset, ok := h.Offsets[refId] var offset Offset
if !ok || offset == nil { if err := h.Offsets.Entry(refId, &offset); err != nil || offset.Len == 0 {
return nil return nil
} }
...@@ -88,7 +93,11 @@ func (h *Hovers) Close() error { ...@@ -88,7 +93,11 @@ func (h *Hovers) Close() error {
return err return err
} }
return os.Remove(h.File.Name()) if err := os.Remove(h.File.Name()); err != nil {
return err
}
return h.Offsets.Close()
} }
func (h *Hovers) addData(line []byte) error { func (h *Hovers) addData(line []byte) error {
...@@ -117,10 +126,10 @@ func (h *Hovers) addData(line []byte) error { ...@@ -117,10 +126,10 @@ func (h *Hovers) addData(line []byte) error {
return err return err
} }
h.Offsets[rawData.Id] = &Offset{At: h.CurrentOffset, Len: n} offset := Offset{At: int32(h.CurrentOffset), Len: int32(n)}
h.CurrentOffset += n h.CurrentOffset += n
return nil return h.Offsets.SetEntry(rawData.Id, &offset)
} }
func (h *Hovers) addHoverRef(line []byte) error { func (h *Hovers) addHoverRef(line []byte) error {
...@@ -129,9 +138,12 @@ func (h *Hovers) addHoverRef(line []byte) error { ...@@ -129,9 +138,12 @@ func (h *Hovers) addHoverRef(line []byte) error {
return err return err
} }
h.Offsets[hoverRef.ResultSetId] = h.Offsets[hoverRef.HoverId] var offset Offset
if err := h.Offsets.Entry(hoverRef.HoverId, &offset); err != nil {
return err
}
return nil return h.Offsets.SetEntry(hoverRef.ResultSetId, &offset)
} }
func (h *Hovers) addResultSetRef(line []byte) error { func (h *Hovers) addResultSetRef(line []byte) error {
...@@ -140,13 +152,10 @@ func (h *Hovers) addResultSetRef(line []byte) error { ...@@ -140,13 +152,10 @@ func (h *Hovers) addResultSetRef(line []byte) error {
return err return err
} }
offset, ok := h.Offsets[ref.ResultSetId] var offset Offset
if !ok { if err := h.Offsets.Entry(ref.ResultSetId, &offset); err != nil {
return nil return nil
} }
h.Offsets[ref.RefId] = offset return h.Offsets.SetEntry(ref.RefId, &offset)
delete(h.Offsets, ref.ResultSetId)
return nil
} }
...@@ -9,6 +9,10 @@ import ( ...@@ -9,6 +9,10 @@ import (
func TestHoversRead(t *testing.T) { func TestHoversRead(t *testing.T) {
h := setupHovers(t) h := setupHovers(t)
var offset Offset
require.NoError(t, h.Offsets.Entry(2, &offset))
require.Equal(t, Offset{At: 0, Len: 19}, offset)
require.Equal(t, `[{"value":"hello"}]`, string(h.For(1))) require.Equal(t, `[{"value":"hello"}]`, string(h.For(1)))
require.NoError(t, h.Close()) require.NoError(t, h.Close())
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment