⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cursor.h

📁 最新版本!fastdb是高效的内存数据库系统
💻 H
📖 第 1 页 / 共 2 页
字号:
    /**
     * Set destination for selected record
     * rec - buffer to which fields of current record will be fetched
     */
    void setRecord(void* rec) { 
        record = (byte*)rec;
    }

    /**
     * Get pointer to the location where fields of the current record are fetched
     * @return pointer to the memory location set by cursor constructor or setRecord method
     */
    void* getRecord() { 
        return record;
    }

    /**
     * Check if record with specified OID is in selection
     * @return <code>true</code> if record with such OID was selected
     */
    bool isInSelection(oid_t oid);


    /**
     * Fetch current record.
     * You should use this method only if prefetch mode is disabled 
     */
    void fetch() { 
        assert(!(db->currIndex[currId] 
                 & (dbInternalObjectMarker|dbFreeHandleMarker)));
        table->columns->fetchRecordFields(record, 
                                          (byte*)db->getRow(currId));
    }

    /**
     * Check if there is more records in the selection
     */
    bool hasNext() const;
    
  protected: 
    dbDatabase*        db;
    dbTableDescriptor* table;
    dbCursorType       type;
    dbCursorType       defaultType;
    dbSelection        selection;
    bool               allRecords;
    oid_t              firstId;
    oid_t              lastId;
    oid_t              currId;
    byte*              record;
    size_t             limit;

    int4*              bitmap; // bitmap to avoid duplicates
    size_t             bitmapSize;
    bool               eliminateDuplicates;
    bool               checkForDuplicatedIsEnabled;
    bool               prefetch;
    bool               removed; // current record was removed
    bool               lastRecordWasDeleted; //last record was deleted

    size_t             stmtLimitStart;
    size_t             stmtLimitLen;
    size_t             nSkipped;

    void*              paramBase;
    
    void checkForDuplicates();
    void deallocateBitmap();

    bool isMarked(oid_t oid) { 
        return bitmap != NULL && (bitmap[oid >> 5] & (1 << (oid & 31))) != 0;
    }

    void setStatementLimit(dbQuery const& q) { 
        stmtLimitStart = q.stmtLimitStartPtr != NULL ? (nat4)*q.stmtLimitStartPtr : q.stmtLimitStart;
        stmtLimitLen = q.stmtLimitLenPtr != NULL ? (nat4)*q.stmtLimitLenPtr : q.stmtLimitLen;
    }

    void truncateSelection() { 
        selection.truncate(stmtLimitStart, stmtLimitLen);
    }

    void mark(oid_t oid) { 
        if (bitmap != NULL) { 
            bitmap[oid >> 5] |= 1 << (oid & 31);
        }
    }    

    bool add(oid_t oid) { 
        if (selection.nRows < limit && selection.nRows < stmtLimitLen) { 
            if (nSkipped < stmtLimitStart) { 
                nSkipped += 1;
                return true;
            }
            if (eliminateDuplicates) { 
                if (bitmap[oid >> 5] & (1 << (oid & 31))) { 
                    return true;
                }
                bitmap[oid >> 5] |= 1 << (oid & 31);
            } 
            selection.add(oid);
            return selection.nRows < limit;
        } 
        return false;
    }

    byte* fetchNext();
    byte* fetchPrev();

    bool gotoNext();
    bool gotoPrev(); 
    bool gotoFirst();
    bool gotoLast();
    
    bool moveNext();
    bool movePrev();

    void setCurrent(dbAnyReference const& ref);

    void adjustReferences(size_t base, size_t size, long shift) { 
        if (currId != 0 && record != NULL) { 
            table->columns->adjustReferences(record, base, size, shift);
        }
    }

    dbAnyCursor(dbTableDescriptor& aTable, dbCursorType aType, byte* rec)
    : table(&aTable),type(aType),defaultType(aType),
      allRecords(false),currId(0),record(rec)
    {
        db = aTable.db;
        limit = dbDefaultSelectionLimit;
        prefetch = rec != NULL;
        removed = false;
        bitmap = NULL; 
        bitmapSize = 0;
        eliminateDuplicates = false;
        checkForDuplicatedIsEnabled = true;
        paramBase = NULL;
        stmtLimitLen = dbDefaultSelectionLimit;
        stmtLimitStart = 0;
        nSkipped = 0;
    }
  public:
    dbAnyCursor() 
    : table(NULL),type(dbCursorViewOnly),defaultType(dbCursorViewOnly),
          allRecords(false),currId(0),record(NULL)
    {
        limit = dbDefaultSelectionLimit;
        prefetch = false;
        removed = false;
        bitmap = NULL;
        bitmapSize = 0;
        eliminateDuplicates = false;
        checkForDuplicatedIsEnabled = true;
        db = NULL;
        paramBase = NULL;
        stmtLimitLen = dbDefaultSelectionLimit;
        stmtLimitStart = 0;
        nSkipped = 0;
    }
    ~dbAnyCursor();
};


/**
 * Cursor template parameterized by table class
 */
template<class T>
class dbCursor : public dbAnyCursor { 
  private:
    // It is not possible to copy cursors
    dbCursor<T> operator = (dbCursor<T> const& src) { 
        return *this;
    } 
	// StoreAge (Itay): block this too
    dbCursor(dbCursor<T> const& src) {assert(0);}

  protected:
    T record;
    
  public:
    /**
     * Cursor constructor
     * @param type cursor type (dbCursorViewOnly by default)
     */
    dbCursor(dbCursorType type = dbCursorViewOnly) 
        : dbAnyCursor(T::dbDescriptor, type, (byte*)&record) {}

    /**
     * Cursor constructor with explicit specification of database.
     * This cursor should be used for unassigned tables. 
     * @param aDb database in which table lookup is performed
     * @param type cursor type (dbCursorViewOnly by default)
     */
    dbCursor(dbDatabase* aDb, dbCursorType type = dbCursorViewOnly)
        : dbAnyCursor(T::dbDescriptor, type, (byte*)&record)
    {
        db = aDb;
        dbTableDescriptor* theTable = db->lookupTable(table);
        if (theTable != NULL) { 
            table = theTable;
        }
    }

    /**
     * Get pointer to the current record
     * @return pointer to the current record or <code>NULL</code> if there is no current record
     */
    T* get() { 
        return currId == 0 ? (T*)NULL : &record; 
    }
    
    /**
     * Get next record
     * @return pointer to the next record or <code>NULL</code> if there is no next record
     */     
    T* next() {
        return (T*)fetchNext();
    }

    /**
     * Get previous record
     * @return pointer to the previous record or <code>NULL</code> if there is no previous record
     */     
    T* prev() { 
        return (T*)fetchPrev();
    }

    /**
     * Get pointer to the first record
     * @return pointer to the first record or <code>NULL</code> if no records were selected
     */
    T* first() { 
        if (gotoFirst()) {
            fetch();
            return &record;
        }
        return NULL;
    }

    /**
     * Get pointer to the last record
     * @return pointer to the last record or <code>NULL</code> if no records were selected
     */
    T* last() { 
        if (gotoLast()) {
            fetch();
            return &record;
        }
        return NULL;
    }    
    
    /**
     * Position cursor on the record with the specified OID
     * @param ref reference to the object
     * @return poistion of the record in the selection or -1 if record with such OID is not in selection
     */
    int seek(dbReference<T> const& ref) { 
        return dbAnyCursor::seek(ref.getOid());
    }

    /**
     * Overloaded operator for accessing components of the current record
     * @return pointer to the current record
     */
    T* operator ->() { 
        assert(currId != 0);
        return &record;
    }

    /**
     * Select record by reference
     * @param ref reference to the record
     * @return pointer to the referenced record
     */
    T* at(dbReference<T> const& ref) { 
        setCurrent(ref);
        return &record;
    }
    
    /**
     * Convert selection to array of reference
     * @param arr [OUT] array of refeences in which references to selected recrods will be placed
     */
    void toArray(dbArray< dbReference<T> >& arr) const { 
        arr.resize(selection.nRows);
        toArrayOfOid((oid_t*)arr.base());
    }

    /**
     * Get current object idenitifer
     * @return reference to the current record
     */
    dbReference<T> currentId() const { 
        return dbReference<T>(currId);
    }

    /**
     * Check if record with specified OID is in selection
     * @return <code>true</code> if record with such OID was selected
     */
    bool isInSelection(dbReference<T>& ref) {
        return dbAnyCursor::isInSelection(ref.getOid());
    }
};

class dbParallelQueryContext { 
  public:
    dbDatabase* const      db;
    dbCompiledQuery* const query;
    oid_t                  firstRow;
    dbTable*               table;
    dbAnyCursor*           cursor;
    dbSelection            selection[dbMaxParallelSearchThreads];

    void search(int i); 

    dbParallelQueryContext(dbDatabase* aDb, dbTable* aTable, 
                           dbCompiledQuery* aQuery, dbAnyCursor* aCursor)
      : db(aDb), query(aQuery), firstRow(aTable->firstRow), table(aTable), cursor(aCursor) {}
};


extern char* strupper(char* s);

extern char* strlower(char* s);

END_FASTDB_NAMESPACE

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -