/* * Copyright (c) 2019 TAOS Data, Inc. * * This program is free software: you can use, redistribute, and/or modify * it under the terms of the GNU Affero General Public License, version 3 * or later ("AGPL"), as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #include "index.h" #include "indexInt.h" #include "index_cache.h" #ifdef USE_LUCENE #include "lucene++/Lucene_c.h" #endif typedef struct SIdxFieldInfo { int fieldId; // generated by index internal int cVersion; int type; // field type } SIdxFieldInfo; static pthread_once_t isInit = PTHREAD_ONCE_INIT; static void indexInit(); static int indexMergeCacheIntoTindex(struct SIndex *sIdx) { if (sIdx == NULL) { return -1; } indexWarn("suid %" PRIu64 " merge cache into tindex", sIdx->suid); return 0; } SIndex *indexOpen(SIndexOpts *opts, const char *path) { pthread_once(&isInit, indexInit); SIndex *sIdx = calloc(1, sizeof(SIndex)); #ifdef USE_LUCENE index_t *index = index_open(path); sIdx->index = index; #endif sIdx->cache = (void*)indexCacheCreate(); sIdx->tindex = NULL; sIdx->fieldObj = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); sIdx->fieldId = 1; sIdx->cVersion = 1; pthread_mutex_init(&sIdx->mtx, NULL); return sIdx; } void indexClose(SIndex *sIdx) { #ifdef USE_LUCENE index_close(sIdex->index); sIdx->index = NULL; #endif indexCacheDestroy(sIdx->cache); taosHashCleanup(sIdx->fieldObj); pthread_mutex_destroy(&sIdx->mtx); free(sIdx); return; } int indexPut(SIndex *index, SArray* fVals, int uid) { #ifdef USE_LUCENE index_document_t *doc = index_document_create(); char buf[16] = {0}; sprintf(buf, "%d", uid); for (int i = 0; i < taosArrayGetSize(fVals); i++) { SIndexTerm *p = taosArrayGetP(fVals, i); index_document_add(doc, (const char *)(p->key), p->nKey, (const char *)(p->val), p->nVal, 1); } index_document_add(doc, NULL, 0, buf, strlen(buf), 0); index_put(index->index, doc); index_document_destroy(doc); #endif //TODO(yihao): reduce the lock range pthread_mutex_lock(&index->mtx); for (int i = 0; i < taosArrayGetSize(fVals); i++) { SIndexTerm *p = taosArrayGetP(fVals, i); SIdxFieldInfo *fi = taosHashGet(index->fieldObj, p->key, p->nKey); if (fi == NULL) { SIdxFieldInfo tfi = {.fieldId = index->fieldId, .type = p->type}; index->cVersion++; index->fieldId++; taosHashPut(index->fieldObj, p->key, p->nKey, &tfi, sizeof(tfi)); } else { //TODO, del } } for (int i = 0; i < taosArrayGetSize(fVals); i++) { SIndexTerm *p = taosArrayGetP(fVals, i); SIdxFieldInfo *fi = taosHashGet(index->fieldObj, p->key, p->nKey); assert(fi != NULL); int32_t fieldId = fi->fieldId; int32_t colType = fi->type; int32_t version = index->cVersion; } pthread_mutex_unlock(&index->mtx); return 1; } int indexSearch(SIndex *index, SIndexMultiTermQuery *multiQuerys, SArray *result) { #ifdef USE_LUCENE EIndexOperatorType opera = multiQuerys->opera; int nQuery = taosArrayGetSize(multiQuerys->query); char **fields = malloc(sizeof(char *) * nQuery); char **keys = malloc(sizeof(char *) * nQuery); int *types = malloc(sizeof(int) * nQuery); for (int i = 0; i < nQuery; i++) { SIndexTermQuery *p = taosArrayGet(multiQuerys->query, i); SIndexTerm *term = p->field_value; fields[i] = calloc(1, term->nKey + 1); keys[i] = calloc(1, term->nVal + 1); memcpy(fields[i], term->key, term->nKey); memcpy(keys[i], term->val, term->nVal); types[i] = (int)(p->type); } int *tResult = NULL; int tsz= 0; index_multi_search(index->index, (const char **)fields, (const char **)keys, types, nQuery, opera, &tResult, &tsz); for (int i = 0; i < tsz; i++) { taosArrayPush(result, &tResult[i]); } for (int i = 0; i < nQuery; i++) { free(fields[i]); free(keys[i]); } free(fields); free(keys); free(types); #endif return 1; } int indexDelete(SIndex *index, SIndexMultiTermQuery *query) { return 1; } int indexRebuild(SIndex *index, SIndexOpts *opts); SIndexOpts *indexOptsCreate() { #ifdef USE_LUCENE #endif return NULL; } void indexOptsDestroy(SIndexOpts *opts) { #ifdef USE_LUCENE #endif } /* * @param: oper * */ SIndexMultiTermQuery *indexMultiTermQueryCreate(EIndexOperatorType opera) { SIndexMultiTermQuery *p = (SIndexMultiTermQuery *)malloc(sizeof(SIndexMultiTermQuery)); if (p == NULL) { return NULL; } p->opera = opera; p->query = taosArrayInit(4, sizeof(SIndexTermQuery)); return p; } void indexMultiTermQueryDestroy(SIndexMultiTermQuery *pQuery) { for (int i = 0; i < taosArrayGetSize(pQuery->query); i++) { SIndexTermQuery *p = (SIndexTermQuery *)taosArrayGet(pQuery->query, i); indexTermDestroy(p->field_value); } taosArrayDestroy(pQuery->query); free(pQuery); }; int indexMultiTermQueryAdd(SIndexMultiTermQuery *pQuery, const char *field, int32_t nFields, const char *value, int32_t nValue, EIndexQueryType type){ SIndexTerm *t = indexTermCreate(field, nFields, value, nValue); if (t == NULL) {return -1;} SIndexTermQuery q = {.type = type, .field_value = t}; taosArrayPush(pQuery->query, &q); return 0; } SIndexTerm *indexTermCreate(const char *key, int32_t nKey, const char *val, int32_t nVal) { SIndexTerm *t = (SIndexTerm *)malloc(sizeof(SIndexTerm)); t->key = (char *)calloc(nKey + 1, 1); memcpy(t->key, key, nKey); t->nKey = nKey; t->val = (char *)calloc(nVal + 1, 1); memcpy(t->val, val, nVal); t->nVal = nVal; return t; } void indexTermDestroy(SIndexTerm *p) { free(p->key); free(p->val); free(p); } SArray *indexMultiTermCreate() { return taosArrayInit(4, sizeof(SIndexTerm *)); } int indexMultiTermAdd(SArray *array, const char *field, int32_t nField, const char *val, int32_t nVal) { SIndexTerm *term = indexTermCreate(field, nField, val, nVal); if (term == NULL) { return -1; } taosArrayPush(array, &term); return 0; } void indexMultiTermDestroy(SArray *array) { for (int32_t i = 0; i < taosArrayGetSize(array); i++) { SIndexTerm *p = taosArrayGetP(array, i); indexTermDestroy(p); } taosArrayDestroy(array); } void indexInit() { //do nothing }