// Create an index on the path. func (col *Col) Index(idxPath []string) (err error) { col.db.schemaLock.Lock() defer col.db.schemaLock.Unlock() idxName := strings.Join(idxPath, INDEX_PATH_SEP) if _, exists := col.indexPaths[idxName]; exists { return fmt.Errorf("Path %v is already indexed", idxPath) } col.indexPaths[idxName] = idxPath idxDir := path.Join(col.db.path, col.name, idxName) if err = os.MkdirAll(idxDir, 0700); err != nil { return err } for i := 0; i < col.db.numParts; i++ { if col.hts[i][idxName], err = data.OpenHashTable(path.Join(idxDir, strconv.Itoa(i))); err != nil { return err } } // Put all documents on the new index col.ForEachDoc(func(id int, doc []byte) (moveOn bool) { var docObj map[string]interface{} if err := json.Unmarshal(doc, &docObj); err != nil { // Skip corrupted document return true } for _, idxVal := range GetIn(docObj, idxPath) { if idxVal != nil { hashKey := StrHash(fmt.Sprint(idxVal)) col.hts[hashKey%col.db.numParts][idxName].Put(hashKey, id) } } return true }) return }
// Load collection schema including index schema. func (col *Col) load() error { if err := os.MkdirAll(path.Join(col.db.path, col.name), 0700); err != nil { return err } col.parts = make([]*data.Partition, col.db.numParts) col.hts = make([]map[string]*data.HashTable, col.db.numParts) for i := 0; i < col.db.numParts; i++ { col.hts[i] = make(map[string]*data.HashTable) } col.indexPaths = make(map[string][]string) // Open collection document partitions for i := 0; i < col.db.numParts; i++ { var err error if col.parts[i], err = data.OpenPartition( path.Join(col.db.path, col.name, DOC_DATA_FILE+strconv.Itoa(i)), path.Join(col.db.path, col.name, DOC_LOOKUP_FILE+strconv.Itoa(i))); err != nil { return err } } // Look for index directories colDirContent, err := ioutil.ReadDir(path.Join(col.db.path, col.name)) if err != nil { return err } for _, htDir := range colDirContent { if !htDir.IsDir() { continue } // Open index partitions idxName := htDir.Name() idxPath := strings.Split(idxName, INDEX_PATH_SEP) col.indexPaths[idxName] = idxPath for i := 0; i < col.db.numParts; i++ { if col.hts[i] == nil { col.hts[i] = make(map[string]*data.HashTable) } if col.hts[i][idxName], err = data.OpenHashTable( path.Join(col.db.path, col.name, idxName, strconv.Itoa(i))); err != nil { return err } } } return nil }