Ignore:
Timestamp:
05/29/13 22:02:43 (11 years ago)
Author:
lyard
Message:
more tweaks to factfits
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Mars/mcore/zfits.h

    r16426 r16443  
    3333        fNumRowsPerTile(0),
    3434        fCurrentRow(-1),
    35         fHeapOff(0)
     35        fHeapOff(0),
     36        fTileSize(0)
    3637    {
    3738        InitCompressionReading();
     
    4748              fNumRowsPerTile(0),
    4849              fCurrentRow(-1),
    49               fHeapOff(0)
     50              fHeapOff(0),
     51              fTileSize(0)
    5052    {
    5153        InitCompressionReading();
     
    6062        fRow++;
    6163        return true;
     64    }
     65protected:
     66
     67    //  Stage the requested row to internal buffer
     68    //  Does NOT return data to users
     69    virtual void StageRow(size_t row, char* dest)
     70    {
     71        if (!fTable.isCompressed)
     72        {
     73            fits::StageRow(row, dest);
     74            return;
     75        }
     76
     77        ReadBinaryRow(row, dest);
    6278    }
    6379
     
    8298    }
    8399
    84     //  Stage the requested row to internal buffer
    85     //  Does NOT return data to users
    86     void StageRow(size_t row, char* dest)
    87     {
    88         if (!fTable.isCompressed)
    89         {
    90             fits::StageRow(row, dest);
    91             return;
    92         }
    93 
    94         ReadBinaryRow(row, dest);
    95     }
    96 
    97100    // Copy decompressed data to location requested by user
    98101    void MoveColumnDataToUserSpace(char* dest, const char* src, const Table::Column& c)
     
    118121
    119122    vector<vector<pair<int64_t, int64_t> > > fCatalog;///< Catalog, i.e. the main table that points to the compressed data.
     123    vector<size_t> fTileSize; ///< size in bytes of each compressed tile
     124    vector<vector<size_t> > fTileOffsets; ///< offset from start of tile of a given compressed column
    120125
    121126    void AllocateBuffers()
     
    127132
    128133        fTransposedBuffer.resize(fTable.bytes_per_row*fNumRowsPerTile);
    129         fCompressedBuffer.resize(fTable.bytes_per_row*fNumRowsPerTile + 1024*1024); //use a bit more memory, in case the compression algorithms uses more
     134        fCompressedBuffer.resize(fTable.bytes_per_row*fNumRowsPerTile + fTable.num_cols); //use a bit more memory for compression flags
    130135    }
    131136
     
    139144        fCatalog.resize(fNumTiles);
    140145
     146        const streampos catalogStart = tellg();
     147
     148        //do the actual reading
    141149        for (uint32_t i=0;i<fNumTiles;i++)
    142150            for (uint32_t j=0;j<fTable.num_cols;j++)
     
    147155                int64_t tempValues[2] = {0,0};
    148156                revcpy<8>(reinterpret_cast<char*>(tempValues), readBuf, 2);
    149 
     157                if (tempValues[0] < 0 || tempValues[1] < 0)
     158                {
     159#ifdef __EXCEPTIONS
     160                    throw runtime_error("ERROR: negative value in the catalog");
     161#else
     162                    gLog << ___err ___ << "ERROR: negative value in the catalog" << endl;
     163                    return;
     164#endif
     165                }
    150166                //add catalog entry
    151167                fCatalog[i].emplace_back(tempValues[0], tempValues[1]);
    152168            }
    153169
     170        //compute the total size of each compressed tile
     171        fTileSize.resize(fNumTiles);
     172        fTileOffsets.resize(fNumTiles);
     173        for (uint32_t i=0;i<fNumTiles;i++)
     174        {
     175            fTileSize[i] = 0;
     176            for (uint32_t j=0;j<fTable.num_cols;j++)
     177            {
     178                fTileSize[i] += fCatalog[i][j].first;
     179                fTileOffsets[i].emplace_back(fCatalog[i][j].second - fCatalog[i][0].second);
     180            }
     181        }
    154182        //see if there is a gap before heap data
    155183        fHeapOff = tellg()+fTable.GetHeapShift();
    156     }
    157 
     184
     185        if (!fCopy.is_open())
     186            return;
     187
     188        //write catalog and heap gap to target file
     189        seekg(catalogStart);
     190
     191        const size_t catSize = fTable.GetHeapShift() + fTable.total_bytes;
     192
     193        vector<char> buf(catSize);
     194        read(buf.data(), catSize);
     195
     196        fCopy.write(buf.data(), catSize);
     197        if (!fCopy)
     198            clear(rdstate()|ios::badbit);
     199    }
     200    //overrides fits.h method with empty one
     201    //work is done in ReadBinaryRow because it requires volatile data from ReadBinaryRow
     202    virtual void WriteRowToCopyFile(size_t )
     203    {
     204
     205    }
    158206    // Compressed versin of the read row
    159207    bool ReadBinaryRow(const size_t &rowNum, char *bufferToRead)
     
    164212        const uint32_t requestedTile = rowNum/fNumRowsPerTile;
    165213        const uint32_t currentTile   = fCurrentRow/fNumRowsPerTile;
     214        const size_t   previousRow   = fCurrentRow;
    166215
    167216        fCurrentRow = rowNum;
     
    171220        {
    172221            //read yet another chunk from the file
    173             //the size that we should read is in the catalog. we should sum up the sizes of all columns
    174             const uint32_t currentCatRow = fCurrentRow/fNumRowsPerTile;
    175 
    176             int64_t sizeToRead  = 0;
    177             for (uint32_t i=0;i<fCatalog[currentCatRow].size();i++)
    178                 sizeToRead += fCatalog[currentCatRow][i].first;
     222            const int64_t sizeToRead = fTileSize[requestedTile];
    179223
    180224            //skip to the beginning of the tile
    181             seekg(fHeapOff+fCatalog[currentCatRow][0].second);
     225            seekg(fHeapOff+fCatalog[requestedTile][0].second);
    182226            read(fCompressedBuffer.data(), sizeToRead);
    183227
     228            if (fCurrentRow == previousRow+1 &&
     229                fCopy.is_open() &&
     230                fCopy.good())
     231            {
     232                fCopy.write(fCompressedBuffer.data(), sizeToRead);
     233                if (!fCopy)
     234                    clear(rdstate()|ios::badbit);
     235            }
     236            else
     237                if (fCopy.is_open())
     238                    clear(rdstate()|ios::badbit);
     239
    184240            const uint32_t thisRoundNumRows = (GetNumRows()<fCurrentRow + fNumRowsPerTile) ? GetNumRows()%fNumRowsPerTile : fNumRowsPerTile;
    185241
    186242            //uncompress it
    187             UncompressBuffer(currentCatRow, thisRoundNumRows);
     243            UncompressBuffer(requestedTile, thisRoundNumRows);
    188244
    189245            // pointer to column (source buffer)
     
    301357
    302358            //get the compression flag
    303             const int64_t compressedOffset = fCatalog[catalogCurrentRow][i].second - fCatalog[catalogCurrentRow][0].second;
     359            const int64_t compressedOffset = fTileOffsets[catalogCurrentRow][i];//fCatalog[catalogCurrentRow][i].second - fCatalog[catalogCurrentRow][0].second;
    304360            const char    compressedFlag   = fCompressedBuffer[compressedOffset];
    305361
Note: See TracChangeset for help on using the changeset viewer.