示例#1
0
// Open opens a database at the provided path.
// If the file does not exist then it will be created automatically.
func Open(path string) (*DB, error) {
	db := &DB{}
	db.keys = btree.New(16, nil)
	db.exps = btree.New(16, &exctx{db})
	db.idxs = make(map[string]*index)
	db.config = Config{
		SyncPolicy:           EverySecond,
		AutoShrinkPercentage: 100,
		AutoShrinkMinSize:    32 * 1024 * 1024,
	}
	db.persist = path != ":memory:"
	if db.persist {
		var err error
		// Hardcoding 0666 as the default mode.
		db.file, err = os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0666)
		if err != nil {
			return nil, err
		}
		if err := db.load(); err != nil {
			_ = db.file.Close()
			return nil, err
		}
		db.bufw = bufio.NewWriter(db.file)
	}
	// start the background manager.
	go db.backgroundManager()
	return db, nil
}
示例#2
0
// createIndex is called by CreateIndex() and CreateSpatialIndex()
func (db *DB) createIndex(
	name string,
	pattern string,
	less func(a, b string) bool,
	rect func(item string) (min, max []float64),
) error {
	db.mu.Lock()
	defer db.mu.Unlock()
	if db.closed {
		return ErrDatabaseClosed
	}
	if name == "" {
		return ErrIndexExists
	}
	if _, ok := db.idxs[name]; ok {
		return ErrIndexExists
	}
	idx := &index{
		name:    name,
		pattern: pattern,
		less:    less,
		rect:    rect,
		db:      db,
	}
	if less != nil {
		idx.btr = btree.New(16, idx)
	}
	if rect != nil {
		idx.rtr = rtree.New(idx)
	}
	db.keys.Ascend(func(item btree.Item) bool {
		dbi := item.(*dbItem)
		if !wildcardMatch(dbi.key, idx.pattern) {
			return true
		}
		if less != nil {
			idx.btr.ReplaceOrInsert(dbi)
		}
		if rect != nil {
			idx.rtr.Insert(dbi)
		}
		return true
	})
	db.idxs[name] = idx
	return nil
}