fork of https://github.com/sourcegraph/zoekt
1// Copyright 2016 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//go:build linux || darwin
16
17package zoekt
18
19import (
20 "fmt"
21 "log"
22 "os"
23 "syscall"
24)
25
26type mmapedIndexFile struct {
27 name string
28 size uint32
29 data []byte
30}
31
32func (f *mmapedIndexFile) Read(off, sz uint32) ([]byte, error) {
33 if off > off+sz || off+sz > uint32(len(f.data)) {
34 return nil, fmt.Errorf("out of bounds: %d, len %d, name %s", off+sz, len(f.data), f.name)
35 }
36 return f.data[off : off+sz], nil
37}
38
39func (f *mmapedIndexFile) Name() string {
40 return f.name
41}
42
43func (f *mmapedIndexFile) Size() (uint32, error) {
44 return f.size, nil
45}
46
47func (f *mmapedIndexFile) Close() {
48 if err := syscall.Munmap(f.data); err != nil {
49 log.Printf("WARN failed to Munmap %s: %v", f.name, err)
50 }
51}
52
53// NewIndexFile returns a new index file. The index file takes
54// ownership of the passed in file, and may close it.
55func NewIndexFile(f *os.File) (IndexFile, error) {
56 defer f.Close()
57
58 fi, err := f.Stat()
59 if err != nil {
60 return nil, err
61 }
62
63 sz := fi.Size()
64 if sz >= maxUInt32 {
65 return nil, fmt.Errorf("file %s too large: %d", f.Name(), sz)
66 }
67 r := &mmapedIndexFile{
68 name: f.Name(),
69 size: uint32(sz),
70 }
71
72 rounded := (r.size + 4095) &^ 4095
73 r.data, err = syscall.Mmap(int(f.Fd()), 0, int(rounded), syscall.PROT_READ, syscall.MAP_SHARED)
74 if err != nil {
75 return nil, err
76 }
77
78 return r, err
79}