/* * Build update list */ bool CReferenceBuilder::buildUpdateList(std::vector<TUpdateList>& updateList, const std::string& filePath) { vector<string> fileList; NLMISC::CPath::getPathContent(filePath, false, false, true, fileList); if (fileList.empty()) return true; // sort table by id first then date sort(fileList.begin(), fileList.end()); uint i; for (i=0; i<fileList.size(); ++i) { uint32 tableId; CTimestamp timestamp; if (!CDBDeltaFile::isDeltaFileName(fileList[i], tableId, timestamp)) continue; CDBDeltaFile delta; delta.setup(fileList[i], 0, CTimestamp(), CTimestamp()); if (!delta.preload()) { nlwarning("CReferenceBuilder::buildUpdateList(): failed to preload file '%s', left as is but built reference may be corrupted", fileList[i].c_str()); continue; } CTimestamp starttime, endtime; starttime.fromTime(delta.getStartTimestamp()); endtime.fromTime(delta.getEndTimestamp()); if (updateList.size() <= tableId) updateList.resize(tableId+1); TUpdateList& list = updateList[tableId]; TUpdateList::iterator it; bool insert = true; for (it=list.begin(); it!=list.end(); ++it) { CUpdateFile& update = *it; // ok, insert here if (endtime < update.StartTime) break; // discard any overlap if ((starttime >= update.StartTime && starttime < update.EndTime) || (endtime > update.StartTime && endtime <= update.EndTime)) { insert = false; break; } } if (!insert) continue; CUpdateFile update; update.StartTime = starttime; update.EndTime = endtime; update.Filename = fileList[i]; list.insert(it, update); } return true; }
/* * Concats a delta file to this one */ bool CDBDeltaFile::concat(CDBDeltaFile& delta, const CTimestamp& starttime, const CTimestamp& endtime) { string filepath = _Path+_Name; if (!delta.preload()) { nlwarning("CDBDeltaFile::concat(): failed to concat in file '%s', cannot preload file '%s'", filepath.c_str(), delta._Name.c_str()); return false; } // check file has valid row size if (_Header.RowSize == 0) { setup(_Name, _Path, delta.getRowSize(), starttime, endtime); } else if (_Header.RowSize != delta.getRowSize()) { nlwarning("CDBDeltaFile::concat(): failed, file '%s' has different row size from '%s'", delta._Name.c_str(), filepath.c_str()); return false; } // check & set header ids if (_Header.StartDeltaId == 0 && _Header.EndDeltaId == 0) { // header ids not yet set _Header.StartDeltaId = delta._Header.StartDeltaId; _Header.EndDeltaId = delta._Header.EndDeltaId; } else if (_Header.EndDeltaId == delta._Header.StartDeltaId || _Header.EndDeltaId == delta._Header.StartDeltaId-1) { // update delta id _Header.EndDeltaId = delta._Header.EndDeltaId; } else { // failure! nlwarning("CDBDeltaFile::concat(): non consecutive delta ids in delta files: file '%s' end=%d, file '%s' start=%d", filepath.c_str(), _Header.EndDeltaId, delta._Path.c_str(), delta._Header.StartDeltaId); return false; } vector<uint8> databuffer(_Header.RowSize); uint8* data = &(databuffer[0]); uint32 row; // read a row, and write it if read row is valid // loop till there are rows to read while (true) { if (!delta.read(row, data)) { nlwarning("CDBDeltaFile::concat(): failed to concat to '%s', cannot read next row update in file '%s'", filepath.c_str(), delta._Name.c_str()); return false; } if (row == 0xffffffff) break; if (!write(row, data)) { nlwarning("CDBDeltaFile::concat(): failed to write row '%d' update in file '%s'", row, filepath.c_str()); return false; } } return true; }