Esempio n. 1
0
// LoadSegs laods all existing segment files available
// matching provided base path. The base path should contain
// the path to the segment file and the segment file prefix.
// example: "/path/to/segment/files/prefix_"
func LoadSegs(base string, size int64, lock bool) (segs []*Segment, err error) {
	segs = []*Segment{}

	for i := 0; true; i++ {
		path := base + strconv.Itoa(i)
		file, err := os.OpenFile(path, os.O_RDWR, 0644)
		if err != nil {
			break
		}

		// don't need this
		defer file.Close()

		seg, err := memmap.MapFile(file, size)
		if err != nil {
			return nil, err
		}

		if lock {
			if err := seg.Lock(); err != nil {
				go seg.Close()
				return nil, err
			}
		}

		segs = append(segs, &Segment{seg, 0})
	}

	return segs, nil
}
Esempio n. 2
0
// ensure makes sure that segments upto given index exists and are valid.
// This will check from current segment length upto given position.
// This will also pre allocate an additional segment file/mmap.
func (s *Store) ensure(n int64) (err error) {
	// +1 preallocate
	num := int(n) + 1

	// fast path
	s.segmx.RLock()
	if num < len(s.segs) {
		s.segmx.RUnlock()
		return nil
	}
	s.segmx.RUnlock()

	// slow path
	s.segmx.Lock()
	defer s.segmx.Unlock()

	available := len(s.segs)
	if num < available {
		return nil
	}

	for i := available; i <= num; i++ {
		path := s.base + strconv.Itoa(i)
		file, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0644)
		if err != nil {
			return err
		}

		// don't need this
		defer file.Close()

		seg, err := memmap.MapFile(file, s.size)
		if err != nil {
			return err
		}

		if err := seg.Lock(); err != nil {
			go seg.Close()
			return err
		}

		s.segs = append(s.segs, &Segment{seg, 0})
	}

	return nil
}