File indexing completed on 2024-05-12 04:38:05

0001 /*
0002     SPDX-FileCopyrightText: 2008 David Nolden <david.nolden.kdevelop@art-master.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #ifndef KDEVPLATFORM_TOPDUCONTEXTDYNAMICDATA_H
0008 #define KDEVPLATFORM_TOPDUCONTEXTDYNAMICDATA_H
0009 
0010 #include <QVector>
0011 #include <QByteArray>
0012 #include "problem.h"
0013 
0014 class QFile;
0015 
0016 namespace KDevelop {
0017 class TopDUContext;
0018 class DUContext;
0019 class Declaration;
0020 class IndexedString;
0021 class IndexedDUContext;
0022 class DUChainBaseData;
0023 
0024 ///This class contains dynamic data of a top-context, and also the repository that contains all the data within this top-context.
0025 class TopDUContextDynamicData
0026 {
0027 public:
0028     explicit TopDUContextDynamicData(TopDUContext* topContext);
0029     ~TopDUContextDynamicData();
0030 
0031     void clear();
0032 
0033     /**
0034      * Allocates an index for the given declaration in this top-context.
0035      * The returned index is never zero.
0036      * @param temporary whether the declaration is temporary. If it is, it will be stored separately, not stored to disk,
0037      *                   and a duchain write-lock is not needed. Else, you need a write-lock when calling this.
0038      */
0039     uint allocateDeclarationIndex(Declaration* decl, bool temporary);
0040 
0041     Declaration* declarationForIndex(uint index) const;
0042 
0043     bool isDeclarationForIndexLoaded(uint index) const;
0044 
0045     void clearDeclarationIndex(Declaration* decl);
0046 
0047     /**
0048      * Allocates an index for the given context in this top-context.
0049      * The returned index is never zero.
0050      * @param temporary whether the context is temporary. If it is, it will be stored separately, not stored to disk,
0051      *                   and a duchain write-lock is not needed. Else, you need a write-lock when calling this.
0052      */
0053     uint allocateContextIndex(DUContext* ctx, bool temporary);
0054 
0055     DUContext* contextForIndex(uint index) const;
0056 
0057     bool isContextForIndexLoaded(uint index) const;
0058 
0059     void clearContextIndex(DUContext* ctx);
0060 
0061     /**
0062      * Allocates an index for the given problem in this top-context.
0063      * The returned index is never zero.
0064      */
0065     uint allocateProblemIndex(const ProblemPointer& problem);
0066     ProblemPointer problemForIndex(uint index) const;
0067     void clearProblems();
0068 
0069     ///Stores this top-context to disk
0070     void store();
0071 
0072     ///Stores all remnants of this top-context that are on disk. The top-context will be fully dynamic after this.
0073     void deleteOnDisk();
0074 
0075     ///Whether this top-context is on disk(Either has been loaded, or has been stored)
0076     bool isOnDisk() const;
0077 
0078     ///Loads the top-context from disk, or returns zero on failure. The top-context will not be registered anywhere, and will have no ParsingEnvironmentFile assigned.
0079     ///Also loads all imported contexts. The Declarations/Contexts will be correctly initialized, and put into the symbol tables if needed.
0080     static TopDUContext* load(uint topContextIndex);
0081 
0082     ///Loads only the url out of the data stored on disk for the top-context.
0083     static IndexedString loadUrl(uint topContextIndex);
0084 
0085     static bool fileExists(uint topContextIndex);
0086 
0087     ///Loads only the list of importers out of the data stored on disk for the top-context.
0088     static QList<IndexedDUContext> loadImporters(uint topContextIndex);
0089 
0090     static QList<IndexedDUContext> loadImports(uint topContextIndex);
0091 
0092     bool isTemporaryContextIndex(uint index) const;
0093     bool isTemporaryDeclarationIndex(uint index) const;
0094 
0095     bool m_deleting; ///Flag used during destruction
0096 
0097     struct ItemDataInfo
0098     {
0099         uint dataOffset; /// Offset of the data
0100         uint parentContext; /// Parent context of the data (0 means the global context)
0101     };
0102 
0103     struct ArrayWithPosition
0104     {
0105         QByteArray array;
0106         uint position;
0107     };
0108 
0109 private:
0110     bool hasChanged() const;
0111 
0112     void unmap();
0113     //Converts away from an mmap opened file to a data array
0114 
0115     QString filePath() const;
0116 
0117     void loadData() const;
0118 
0119     const char* pointerInData(uint offset) const;
0120 
0121     ItemDataInfo writeDataInfo(const ItemDataInfo& info, const DUChainBaseData* data, uint& totalDataOffset);
0122 
0123     TopDUContext* m_topContext;
0124 
0125     template <class Item>
0126     struct DUChainItemStorage
0127     {
0128         explicit DUChainItemStorage(TopDUContextDynamicData* data);
0129         ~DUChainItemStorage();
0130 
0131         void clearItems();
0132         bool itemsHaveChanged() const;
0133 
0134         void storeData(uint& currentDataOffset, const QVector<ArrayWithPosition>& oldData);
0135         Item itemForIndex(uint index) const;
0136 
0137         void clearItemIndex(const Item& item, const uint index);
0138 
0139         uint allocateItemIndex(const Item& item, const bool temporary);
0140 
0141         void deleteOnDisk();
0142         bool isItemForIndexLoaded(uint index) const;
0143 
0144         void loadData(QFile* file) const;
0145         void writeData(QFile* file);
0146 
0147         //May contain zero items if they were deleted
0148         mutable QVector<Item> items;
0149         mutable QVector<ItemDataInfo> offsets;
0150         QVector<Item> temporaryItems;
0151         TopDUContextDynamicData* const data;
0152     };
0153 
0154     DUChainItemStorage<DUContext*> m_contexts;
0155     DUChainItemStorage<Declaration*> m_declarations;
0156     DUChainItemStorage<ProblemPointer> m_problems;
0157 
0158     //For temporary declarations that will not be stored to disk, like template instantiations
0159 
0160     mutable QVector<ArrayWithPosition> m_data;
0161     mutable QVector<ArrayWithPosition> m_topContextData;
0162     bool m_onDisk;
0163     mutable bool m_dataLoaded;
0164 
0165     mutable QFile* m_mappedFile;
0166     mutable uchar* m_mappedData;
0167     mutable size_t m_mappedDataSize;
0168     mutable bool m_itemRetrievalForbidden;
0169 };
0170 }
0171 
0172 Q_DECLARE_TYPEINFO(KDevelop::TopDUContextDynamicData::ItemDataInfo, Q_PRIMITIVE_TYPE);
0173 Q_DECLARE_TYPEINFO(KDevelop::TopDUContextDynamicData::ArrayWithPosition, Q_MOVABLE_TYPE);
0174 
0175 #endif