Ejemplo n.º 1
0
void LCDataFileWrite::RecordData()
{
	//! *** If reference required, compute the value and pass to the next function 
	if(WriteRef)
		RecordData(t0+iDatWrite*dt);
	else
		RecordData(0.);
}
    RecordData KVRecordStore::_getDataFor(const KVDictionary *db, OperationContext* txn, const RecordId& id, bool skipPessimisticLocking) {
        Slice value;
        Status status = db->get(txn, Slice::of(KeyString(id)), value, skipPessimisticLocking);
        if (!status.isOK()) {
            if (status.code() == ErrorCodes::NoSuchKey) {
                return RecordData(nullptr, 0);
            } else {
                log() << "storage engine get() failed, operation will fail: " << status.toString();
                uasserted(28922, status.toString());
            }
        }

        // Return an owned RecordData that uses the SharedBuffer from `value'
        return RecordData(std::move(value.ownedBuf()), value.size());
    }
Ejemplo n.º 3
0
RecordData Database::get(const RecordID& id) const
{
	Dbt key(id.data(), id.size());
	Dbt data;
	thread_local static std::vector<char> buffer(256);
		
	while (true)
	{
		try
		{
			data.set_flags(DB_DBT_USERMEM);
			data.set_data(buffer.data());
			data.set_ulen(buffer.size());
			const int err = dbMain_.get(/*txnid*/nullptr, &key, &data, /*flags*/0);
			assert (err == 0);
			break;
		}
		catch(DbException const& ex)
		{
			if (ex.get_errno() !=  DB_BUFFER_SMALL)
			{
				throw;
			}

			buffer.resize(data.get_size() * 1.5);
		}
	}
	
	return RecordData(data);
}
Ejemplo n.º 4
0
db_iterator Database::dirs_begin() const
{
    Dbc* pCursor = nullptr;
	dbDirs_.cursor(NULL, &pCursor, 0);
	assert(pCursor);
	
    RecordID id;
    Dbt key;
    Dbt data;
    
    key.set_flags(DB_DBT_USERMEM);
    key.set_data(id.data());
    key.set_ulen(id.size());
    
    const int err = pCursor->get(&key, &data, DB_FIRST);
    
    if (err)
    {
        pCursor->close();
        
        if (err != DB_NOTFOUND)
        {
            throw DbException("Failed to obtain first directory record", err);
        }
        
        return dirs_end();
    }
    
    return db_iterator(pCursor, make_Record(std::move(id), RecordData(data)));
}
Ejemplo n.º 5
0
Records Database::children(const RecordID& idParent) const
{
	Records result;
	
	Dbc* pCursor = nullptr;
	dbParentId_.cursor(NULL, &pCursor, 0);
	assert(pCursor);
    
    BOOST_SCOPE_EXIT(&pCursor) 
    {
        pCursor->close();
    } BOOST_SCOPE_EXIT_END
	
	Dbt keyParent(idParent.data(), idParent.size());
	Dbt keyChild;
	Dbt record;
	
	int res = pCursor->pget(&keyParent, &keyChild, &record, DB_SET);
	
	while (res == 0)
	{
		result.push_back(make_Record(RecordID(keyChild), RecordData(record)));
		res = pCursor->pget(&keyParent, &keyChild, &record, DB_NEXT_DUP);
	}
	
	return result;
}
Ejemplo n.º 6
0
    boost::optional<Record> next() final {
        if (_eof) {
            return {};
        }

        int status = _stmt->step();
        // Reached end of result rows.
        if (status == SQLITE_DONE) {
            _eof = true;
            _savedId = RecordId(_startIdNum);
            return {};
        }

        // Checks no error was thrown and that step retrieved a row.
        embedded::checkStatus(status, SQLITE_ROW, "_stmt->step() in MobileCursor's next");

        long long recId = _stmt->getColInt(0);
        const void* data = _stmt->getColBlob(1);
        int64_t dataSize = _stmt->getColBytes(1);

        _savedId = RecordId(recId);
        // The data returned from sqlite3_column_blob is only valid until the next call to
        // sqlite3_step. Using getOwned copies the buffer so the data is not invalidated.
        return {{_savedId, RecordData(static_cast<const char*>(data), dataSize).getOwned()}};
    }
Ejemplo n.º 7
0
StatusWith<RecordData> MobileRecordStore::updateWithDamages(
    OperationContext* opCtx,
    const RecordId& recId,
    const RecordData& oldRec,
    const char* damageSource,
    const mutablebson::DamageVector& damages) {
    return RecordData();
}
Ejemplo n.º 8
0
 bool HeapRecordStoreBtree::findRecord(OperationContext* txn,
                                       const RecordId& loc, RecordData* out) const {
     Records::const_iterator it = _records.find(loc);
     if ( it == _records.end() )
         return false;
     const Record& rec = it->second;
     *out = RecordData(rec.data.get(), rec.dataSize);
     return true;
 }
Ejemplo n.º 9
0
// Retrieve the value from a positioned cursor.
RecordData WiredTigerRecordStore::_getData(const WiredTigerCursor& cursor) const {
    WT_ITEM value;
    int ret = cursor->get_value(cursor.get(), &value);
    invariantWTOK(ret);

    SharedBuffer data = SharedBuffer::allocate(value.size);
    memcpy(data.get(), value.data, value.size);
    return RecordData(data, value.size);
}
Ejemplo n.º 10
0
Record Database::find(const std::string& fileName) const
{
	Dbt key;
	Dbt data;
	
	Dbt fileNameKey(const_cast<char*>(fileName.data()), fileName.size());
	const int err = dbFilename_.pget(nullptr, &fileNameKey, &key, &data, 0);
	
	if (err == DB_NOTFOUND)
	{
		return make_Record(NULL_RECORD_ID, RecordData());
	}
	
	if (err)
	{
		throw DbException("Failed to obtain record by filename key", err);
	}
	
	return make_Record(RecordID(key), RecordData(data));
}
bool TerarkDbRecordStore::findRecord(OperationContext* txn,
								   const RecordId& id,
								   RecordData* out) const {
	if (id.isNull())
		return false;
    llong recIdx = id.repr() - 1;
	CompositeTable* tab = m_table->m_tab.get();
    auto& td = m_table->getMyThreadData();
    tab->getValue(recIdx, &td.m_buf, &*td.m_dbCtx);
    SharedBuffer bson = td.m_coder.decode(&tab->rowSchema(), td.m_buf);

//  size_t bufsize = sizeof(SharedBuffer::Holder) + bson.objsize();
    int bufsize = ConstDataView(bson.get()).read<LittleEndian<int>>();
    *out = RecordData(bson, bufsize);
    return true;
}
Ejemplo n.º 12
0
    RecordData RocksRecordStore::dataFor( OperationContext* txn, const DiskLoc& loc) const {
        // TODO investigate using cursor API to get a Slice and avoid double copying.
        std::string value;

        // XXX not using a Snapshot here
        rocksdb::Status status = _db->Get( _readOptions(), _columnFamily, _makeKey( loc ), &value );

        if ( !status.ok() ) {
            log() << "rocks Get failed, blowing up: " << status.ToString();
            invariant( false );
        }

        boost::shared_array<char> data( new char[value.size()] );
        memcpy( data.get(), value.data(), value.size() );

        return RecordData( data.get(), value.size(), data );
    }
Ejemplo n.º 13
0
bool MobileRecordStore::findRecord(OperationContext* opCtx,
                                   const RecordId& recId,
                                   RecordData* rd) const {
    MobileSession* session = MobileRecoveryUnit::get(opCtx)->getSession(opCtx);
    SqliteStatement stmt(*session, "SELECT data FROM \"", _ident, "\" WHERE rec_id = ?;");

    stmt.bindInt(0, recId.repr());

    int status = stmt.step();
    if (status == SQLITE_DONE) {
        return false;
    }
    embedded::checkStatus(status, SQLITE_ROW, "sqlite3_step");

    const void* recData = stmt.getColBlob(0);
    int nBytes = stmt.getColBytes(0);
    *rd = RecordData(static_cast<const char*>(recData), nBytes).getOwned();
    return true;
}
    RecordData KVRecordStore::KVRecordCursor::dataFor(const RecordId& loc) const {
        invariant(_txn);

        // Kind-of tricky:
        //
        // We save the last loc and val that we were pointing to before a call
        // to getNext(). We know that our caller intends to call dataFor() on
        // each loc read this way, so if the given loc is equal to the last 
        // loc, then we can return the last value read, which we own and now
        // pass to the caller with a shared pointer.
        if (!_savedLoc.isNull() && _savedLoc == loc) {
            Slice val = _savedVal;
            invariant(val.mutableData());
            return RecordData(std::move(val.ownedBuf()), val.size());
        } else {
            // .. otherwise something strange happened and the caller actually
            // wants some other data entirely. we should probably never execute
            // this code that often because it is slow to descend the dictionary
            // for every value we want to read..
            return _getDataFor(_db, _txn, loc);
        }
    }
Ejemplo n.º 15
0
db_iterator Database::dirs_end() const
{
    return db_iterator(nullptr, make_Record(NULL_RECORD_ID, RecordData()));
}
Ejemplo n.º 16
0
    void RecordData(int8 * pEightData, uint32 dwNumElements, uint32 dwCurElement)
	{
		RecordData( pEightData, dwNumElements, dwCurElement);
	}
Ejemplo n.º 17
0
    void RecordData(int16 * pSixteenData,  uint32 dwNumElements, uint32 dwCurElement)
	{
		RecordData( pSixteenData, NULL, dwNumElements, dwCurElement);
	}
void CGameFrameWork::AnimateObjects()
{
	if (m_bMove && m_vecBlock.size() < 16)
	{
		MoveBlock();

		int cnt = 0;

		for (auto p = m_vecBlock.cbegin(); p != m_vecBlock.cend(); ++p)
			if (dynamic_cast<CBlock*>(*p)->GetBlockState() == BLOCK_MOVE)
				++cnt;

		if (0 == cnt)
		{
			m_bMove = false;

			///////////////////////////////////////////////////////
			if (!m_bReplay)
			{
				CreateBlock();

				if (m_bRecord)
					m_vecRecord.push_back(RecordData(elapsedTime.count(), m_eKeyDir, m_NewBlockPos));
			}

			else
				CreateBlock(m_vecRecord[m_nReplayCnt++].newBlockPos);
			///////////////////////////////////////////////////////


			for (auto p = m_vecBlock.begin(); p != m_vecBlock.end();)
			{
				if (dynamic_cast<CBlock*>(*p)->GetBlockInfo().addCheck == 1)
				{
					SAFE_DELETE(*p);
					p = m_vecBlock.erase(p);

					continue;
				}

				else if (dynamic_cast<CBlock*>(*p)->GetBlockInfo().addCheck == 2)
				{
					int val = dynamic_cast<CBlock*>(*p)->GetBlockInfo().value;

					dynamic_cast<CBlock*>(*p)->SetBlockValue(val * 2);
					dynamic_cast<CBlock*>(*p)->SetBlockBmp(val * 2);

					dynamic_cast<CBlock*>(*p)->SetBlockAddCheck(0);

					m_nScore += val * 2;
				}

				++p;
			}
		}
	}

	for (auto p = m_vecBlock.begin(); p != m_vecBlock.end(); ++p)
	{
		int idx = dynamic_cast<CBlock*>(*p)->GetBlockInfo().index;

		Point2D pt = dynamic_cast<CBoard*>(m_pBoard)->GetTile()[idx]->pos;

		if (pt.x != dynamic_cast<CBlock*>(*p)->GetBlockInfo().pos.x ||
			pt.y != dynamic_cast<CBlock*>(*p)->GetBlockInfo().pos.y)
		{
			dynamic_cast<CBlock*>(*p)->Move();
		}

		else
			dynamic_cast<CBlock*>(*p)->SetBlockState(BLOCK_STOP);
	}
}
Ejemplo n.º 19
0
void MainWindow::MeasSequence( void )
{
  double Delta;
  bool a1, a2;

  if ( inMeasDark ) return;
  if ( AskingOverwrite ) return;
  if ( NoticingHaveNotMeasDark ) return;
  if ( MStabOk && MPSet.TuneAtEachStep && MMStab->isBusy() ) return;
  if ( MPSet.qXafsMode ) {
    ShowQXafsProgress();
  }
  if ( ( a1 = isBusyMotorInMeas() ) || ( a2 = mMeasUnits.isBusy() ) ) return;
  if ( MovingToNewSamplePosition ) {
    if ( Changers[ ChangerSelect->currentIndex() ]->unit1()->isBusy()
	 || Changers[ ChangerSelect->currentIndex() ]->unit2()->isBusy() )
      return;
    MovingToNewSamplePosition = false;
  }
  NowTimeDisp->setText( QDateTime::currentDateTime().toString("yy.MM.dd hh:mm:ss") );
  if ( MPSet.qXafsMode ) {
    QXafsMeasSequence();
    return;
  }
  
  switch( MeasStage ) {
    /* 
       0: 測定開始 Repeat = 0
       1: Block = 0
       2: Step = 0, setDwellTime
       3: Goto a Position with a Block and a Step
       4: Prepare to trigger Sensors (only for cnt08)
       5: Trigger Sensors (for all)
       6: Read out Sensors
       10: Draw (Resume point from 99:)
          Step++; if ( Step < MaxStep ) goto 3
          Block++; if ( Block < MaxBlock ) goto 2
          Repeat++; if ( Repeat < MaxRepeat ) toto 1
          when reach here, finish.
       99: pause の時用のステージ
    */
  case 0:
    if ( AutoModeFirst )
      TouchDelegateFile();
    if ( AutoModeButton->isChecked() ) {
      CurrentRpt->setText( QString( "%1 - %2" ).arg( 1 ).arg( MeasA+1 ) );
    } else {
      CurrentRpt->setText( QString::number( 1 ) );
    }
    CurrentPnt->setText( QString::number( 1 ) );
    WriteInfoFile();
    mMeasUnits.clearStage();
    MeasView->SetWindow0( u->any2keV( SBLKUnit, SBlockStartAsDisp[0] ), 0,
			  u->any2keV( SBLKUnit, SBlockStartAsDisp[ SBlocks ] ), 0 );
    statusbar->showMessage( tr( "Start Measurement!" ) );
    MeasStage = 1;
    break;
  case 1:
    // init() == true :: initializing
    if ( mMeasUnits.init() )
      break;
    MeasR = 0;    // Measurement Repeat count
    mMeasUnits.clearStage();
    MeasStage = 2;
    break;
  case 2:
    if ( MeasBlockB->isChecked() )
      break;
    MeasB = 0;    // Measurement Block count
    MeasP = 0;    // Measurement point count
    statusbar->showMessage( tr( "Writing Header." ), 2000 );
    WriteHeader( MeasR );
    MeasStage = 3;
    // break;       MeasStage == 2 の動作はレスポンスを待つ必要なし
  case 3: 
    MeasS = 0;    // Measurement Step count in each block
    mMeasUnits.setDwellTimes( NowDwell = SBlockDwell[ MeasB ] );
    mMeasUnits.setDwellTime();
    MeasStage = 4;
    // break;       MeasStage == 3 もレスポンスを待つ必要なし
    //              (ここで操作したのはセンサーで, Stage == 4 でセンサーを操作しないから)
  case 4:
    if ( !FixedPositionMode ) {
      if ( SMeasInDeg ) {
	Delta = SBlockStartInDeg[MeasB+1] - SBlockStartInDeg[MeasB];
	GoToKeV = u->deg2keV( Delta/SBlockPoints[MeasB]*MeasS + SBlockStartInDeg[MeasB] );
      } else {
	Delta = SBlockStartAsDisp[MeasB+1] - SBlockStartAsDisp[MeasB];
	GoToKeV = u->any2keV( SBLKUnit, Delta / SBlockPoints[MeasB] * MeasS
			      + SBlockStartAsDisp[MeasB] );
      }
      MoveCurThPosKeV( GoToKeV );     // 軸の移動
    }
    mMeasUnits.clearStage();
    if ( MStabOk && MPSet.TuneAtEachStep ) {
      MeasStage = 41;
    } else {
      if ( mMeasUnits.isParent() )
	MeasStage = 5;
      else
	MeasStage = 6;
    }
    break;
  case 41:
    if ( MMStab != NULL ) {
      qDebug() << "Tune Abs " << MPSet.TuneESAbs << "Tune Quick " << MPSet.TuneESQuick;
      if ( MPSet.TuneESAbs ) {
	if ( MPSet.TuneESQuick ) {
	  qDebug() << "Abs Quick";
	  MMStab->GoMaxAbsQ( MPSet.TuneESStart, MPSet.TuneESEnd,
			     MPSet.TuneESSteps, MPSet.TuneESQuickTime );
	} else {
	  qDebug() << "Abs Normal";
	  MMStab->GoMaxAbs( MPSet.TuneESStart, MPSet.TuneESEnd, MPSet.TuneESSteps );
	}
      } else {
	if ( MPSet.TuneESQuick ) {
	  qDebug() << "Rel Quick";
	  MMStab->GoMaxRelQ( MPSet.TuneESStart, MPSet.TuneESSteps, MPSet.TuneESQuickTime );
	} else {
	  qDebug() << "Rel Normal";
	  MMStab->GoMaxRel( MPSet.TuneESStart, MPSet.TuneESSteps );
	}
      }
    }
    if ( mMeasUnits.isParent() )
      MeasStage = 5;
    else
      MeasStage = 6;
    break;
  case 5:
    if ( mMeasUnits.getValue0() == false ) { // only for counters
      mMeasUnits.clearStage();
      MeasStage = 6;
    }
    break;
  case 6:
    if ( mMeasUnits.getValue() == false ) {  // true :: Getting
      mMeasUnits.clearStage();
      MeasStage = 7;
    }
    break;
  case 7:
    mMeasUnits.readValue( MeasVals, MeasCPSs, true );  // true : correct dark
    DispMeasDatas();
    if ( ! conds->I0ShouldBeChecked() || ( MeasCPSs[0] >= conds->I0Threshold() ) ) {
      RecordData();
      MeasP++;
    }
    CurrentPnt->setText( QString::number( MeasP + 1 ) );
    MeasStage = 10;
    if ( inPause ) {
      MeasStage = 99;          // PauseStage
    }
    // don't break
  case 10:                     // This label is resume point from pausing
    MeasView->update();
    if ( conds->I0ShouldBeChecked() && ( MeasCPSs[0] < conds->I0Threshold() ) )
      MeasS--;
    MeasS++;
    if ( !inPause ) {
      if ( MeasS < SBlockPoints[ MeasB ] ) {
        MeasStage = 4;
      } else if ( MeasB < SBlocks-1 ) {
        MeasB++;
        MeasStage = 3;
      } else if ( MeasR < SelRPT->value()-1 ) {
        NewLogMsg( QString( tr( "Meas: Repeat %1" ) ).arg( MeasR + 1 ) );
        WriteHeader2( MeasR );
	SaveI0inMPSet();
        ClearXViewScreenForMeas( MeasView );
        PlayGoOnSound();
        WriteInfoFile2();
        MeasR++;
	if ( AutoModeButton->isChecked() ) {
	  CurrentRpt->setText( QString( "%1 - %2" ).arg( MeasR + 1 ).arg( MeasA+1 ) );
	} else {
	  CurrentRpt->setText( QString::number( MeasR + 1 ) );
	}
	if ( MPSet.isSFluo ) 
	  if ( ! MCACanSaveAllOnMem )
	    // 全部セーブできない時は、1スキャン終わったら
	    // 次のスキャンに備えてメモリクリア (直近の1スキャン分だけ覚えておく)
	    XafsMCAMap.New( MPSet.totalPoints, 1, SFluo->length(), SFluo->chs() );
                               // SelRPT->value() --> 1
        MeasStage = 2;
      } else {               // 終了
	clearUUnits();
	CheckNewMeasFileName();
        statusbar->showMessage( tr( "The Measurement has Finished" ), 4000 );
        NewLogMsg( QString( tr( "Meas: Finished" ) ) );
        WriteHeader2( MeasR );
	SaveI0inMPSet();
        PlayEndingSound();
        WriteInfoFile2();
        MeasTimer->stop();
        inMeas = false;
	MPSet.normallyFinished = true;
        MeasStart->setText( tr( "Start" ) );
        MeasStart->setStyleSheet( NormalEXECB );
        MeasPause->setEnabled( false );
	MeasPause->setHidden( true );
	SignalToStars( XAFS_M_END );
        onMeasFinishWorks();
      }
    }
    break;
  case 99:
    if ( !inPause )
      MeasStage = 10;
    break;
  }
}
Ejemplo n.º 20
0
int64_t WiredTigerRecordStore::cappedDeleteAsNeeded_inlock(OperationContext* txn,
                                                           const RecordId& justInserted) {
    // we do this is a side transaction in case it aborts
    WiredTigerRecoveryUnit* realRecoveryUnit =
        checked_cast<WiredTigerRecoveryUnit*>(txn->releaseRecoveryUnit());
    invariant(realRecoveryUnit);
    WiredTigerSessionCache* sc = realRecoveryUnit->getSessionCache();
    OperationContext::RecoveryUnitState const realRUstate =
        txn->setRecoveryUnit(new WiredTigerRecoveryUnit(sc), OperationContext::kNotInUnitOfWork);

    WiredTigerRecoveryUnit::get(txn)->markNoTicketRequired();  // realRecoveryUnit already has
    WT_SESSION* session = WiredTigerRecoveryUnit::get(txn)->getSession(txn)->getSession();

    int64_t dataSize = _dataSize.load();
    int64_t numRecords = _numRecords.load();

    int64_t sizeOverCap = (dataSize > _cappedMaxSize) ? dataSize - _cappedMaxSize : 0;
    int64_t sizeSaved = 0;
    int64_t docsOverCap = 0, docsRemoved = 0;
    if (_cappedMaxDocs != -1 && numRecords > _cappedMaxDocs)
        docsOverCap = numRecords - _cappedMaxDocs;

    try {
        WriteUnitOfWork wuow(txn);

        WiredTigerCursor curwrap(_uri, _tableId, true, txn);
        WT_CURSOR* c = curwrap.get();
        RecordId newestOld;
        int ret = 0;
        while ((sizeSaved < sizeOverCap || docsRemoved < docsOverCap) && (docsRemoved < 20000) &&
               (ret = WT_OP_CHECK(c->next(c))) == 0) {
            int64_t key;
            ret = c->get_key(c, &key);
            invariantWTOK(ret);

            // don't go past the record we just inserted
            newestOld = _fromKey(key);
            if (newestOld >= justInserted)  // TODO: use oldest uncommitted instead
                break;

            if (_shuttingDown)
                break;

            WT_ITEM old_value;
            invariantWTOK(c->get_value(c, &old_value));

            ++docsRemoved;
            sizeSaved += old_value.size;

            if (_cappedDeleteCallback) {
                uassertStatusOK(_cappedDeleteCallback->aboutToDeleteCapped(
                    txn,
                    newestOld,
                    RecordData(static_cast<const char*>(old_value.data), old_value.size)));
            }
        }

        if (ret != WT_NOTFOUND) {
            invariantWTOK(ret);
        }

        if (docsRemoved > 0) {
            // if we scanned to the end of the collection or past our insert, go back one
            if (ret == WT_NOTFOUND || newestOld >= justInserted) {
                ret = WT_OP_CHECK(c->prev(c));
            }
            invariantWTOK(ret);

            WiredTigerCursor startWrap(_uri, _tableId, true, txn);
            WT_CURSOR* start = startWrap.get();
            ret = WT_OP_CHECK(start->next(start));
            invariantWTOK(ret);

            ret = session->truncate(session, NULL, start, c, NULL);
            if (ret == ENOENT || ret == WT_NOTFOUND) {
                // TODO we should remove this case once SERVER-17141 is resolved
                log() << "Soft failure truncating capped collection. Will try again later.";
                docsRemoved = 0;
            } else {
                invariantWTOK(ret);
                _changeNumRecords(txn, -docsRemoved);
                _increaseDataSize(txn, -sizeSaved);
                wuow.commit();
            }
        }
    } catch (const WriteConflictException& wce) {
        delete txn->releaseRecoveryUnit();
        txn->setRecoveryUnit(realRecoveryUnit, realRUstate);
        log() << "got conflict truncating capped, ignoring";
        return 0;
    } catch (...) {
        delete txn->releaseRecoveryUnit();
        txn->setRecoveryUnit(realRecoveryUnit, realRUstate);
        throw;
    }

    delete txn->releaseRecoveryUnit();
    txn->setRecoveryUnit(realRecoveryUnit, realRUstate);
    return docsRemoved;
}
Ejemplo n.º 21
0
 virtual RecordData dataFor( OperationContext* txn, const DiskLoc& loc) const {
     return RecordData( _dummy.objdata(), _dummy.objsize() );
 }
Ejemplo n.º 22
0
void ScanThread::scanEntry(
			const fs::path& path, 
			const RecordID& parentID, 
			Records& oldRecords,
			bool recursive)
try
{
	if (shouldBreak())
	{
		return;
	}
	
	const bool isDir = fs::is_directory(path);	
	Record newRecord = make_Record(
		NULL_RECORD_ID, 
		RecordData(parentID, /*last write time*/0, isDir, path.string()));

	const std::pair<Records::iterator, Records::iterator> oldRange = 
		std::equal_range(oldRecords.begin(), oldRecords.end(), newRecord, CmpByPath());
	assert(std::distance(oldRange.first, oldRange.second) <= 1);
	
	const Records::iterator itOldRecord = oldRange.first != oldRange.second ?
		oldRange.first : oldRecords.end();

	if (isDir && recursive)
	{
		// if new entry
		if (itOldRecord == oldRecords.end())
		{
            addEntry(std::move(newRecord.second));
		}
	}
	else // file
	{
		if (!isSupportedExtension(path))
		{
			return; // unsupported extension
		}
				
        newRecord.second.header.lastWriteTime = fs::last_write_time(path);
        
		if (itOldRecord == oldRecords.end())
		{
            addEntry(std::move(newRecord.second));
		}
		else if(newRecord.second.header.lastWriteTime != 
				itOldRecord->second.header.lastWriteTime)
		{
			newRecord.first = itOldRecord->first;
            replaceEntry(std::move(newRecord));
		}
	}
	
	// record was processed, so removing from the list
	if (oldRecords.end() != itOldRecord)
	{
		oldRecords.erase(itOldRecord);
	}
}
catch(const fs::filesystem_error& ex)
{
	std::cerr << "Failed to process filesystem element " 
			<< path << ": " << ex.what() << std::endl;
	
	// if the entry is inaccessible due to network resource down
	// it shouldn't be deleted from the database
	if (ex.code().value() != ENOENT)
	{
		const Record fakeRecord = make_Record(NULL_RECORD_ID, 
						RecordData(NULL_RECORD_ID, 0, false, path.string()));
		const Records::iterator itOldRecord = std::lower_bound(
			oldRecords.begin(), oldRecords.end(), fakeRecord, CmpByPath());
		
		// prevent record from deletion
		if (oldRecords.end() != itOldRecord)
		{
			oldRecords.erase(itOldRecord);
		}
	}
}
catch(const std::exception& ex)
{
	std::cerr << "Failed to process filesystem element " 
			<< path << ": " << ex.what() << std::endl;
}