// the argument is the name of the directory or the file name int ibis::skive::write(const char* dt) const { if (vals.empty()) return -1; std::string fnm; indexFileName(fnm, dt); if (fnm.empty()) { return 0; } else if (0 != str && 0 != str->filename() && 0 == fnm.compare(str->filename())) { LOGGER(ibis::gVerbose > 0) << "Warning -- skive::write can not overwrite the index file \"" << fnm << "\" while it is used as a read-only file map"; return 0; } else if (fname != 0 && *fname != 0 && 0 == fnm.compare(fname)) { activate(); // read everything into memory fname = 0; // break the link with the named file } ibis::fileManager::instance().flushFile(fnm.c_str()); int fdes = UnixOpen(fnm.c_str(), OPEN_WRITENEW, OPEN_FILEMODE); if (fdes < 0) { ibis::fileManager::instance().flushFile(fnm.c_str()); fdes = UnixOpen(fnm.c_str(), OPEN_WRITENEW, OPEN_FILEMODE); if (fdes < 0) { LOGGER(ibis::gVerbose > 0) << "Warning -- skive[" << col->partition()->name() << '.' << col->name() << "]::write failed to open \"" << fnm << "\" for writing"; return -2; } } IBIS_BLOCK_GUARD(UnixClose, fdes); #if defined(_WIN32) && defined(_MSC_VER) (void)_setmode(fdes, _O_BINARY); #endif #ifdef FASTBIT_USE_LONG_OFFSETS const bool useoffset64 = true; #else const bool useoffset64 = (getSerialSize()+8 > 0x80000000UL); #endif char header[] = "#IBIS\11\0\0"; header[5] = (char)ibis::index::SKIVE; header[6] = (char)(useoffset64 ? 8 : 4); int ierr = UnixWrite(fdes, header, 8); if (ierr < 8) { LOGGER(ibis::gVerbose > 0) << "Warning -- skive[" << col->partition()->name() << "." << col->name() << "]::write(" << fnm << ") failed to write the 8-byte header, ierr = " << ierr; return -3; } if (useoffset64) ierr = write64(fdes); else ierr = write32(fdes); if (ierr >= 0) { #if defined(FASTBIT_SYNC_WRITE) #if _POSIX_FSYNC+0 > 0 (void) UnixFlush(fdes); // write to disk #elif defined(_WIN32) && defined(_MSC_VER) (void) _commit(fdes); #endif #endif LOGGER(ibis::gVerbose > 3) << "skive[" << col->partition()->name() << "." << col->name() << "]::write wrote " << bits.size() << " bitmap" << (bits.size()>1?"s":"") << " to file " << fnm; } return ierr; } // ibis::skive::write
/// Write the content to a file opened by the caller. This function uses /// 64-bit bitmap offsets. int ibis::skive::write64(int fdes) const { if (vals.empty()) return -4; std::string evt = "skive"; if (ibis::gVerbose > 0) { evt += '['; evt += col->partition()->name(); evt += '.'; evt += col->name(); evt += ']'; } evt += "::write64"; const off_t start = UnixSeek(fdes, 0, SEEK_CUR); if (start < 8) { LOGGER(ibis::gVerbose > 0) << "Warning -- " << evt << " seek(" << fdes << ", 0, SEEK_CUR) returned " << start << ", but a value >= 8 is expected"; return -5; } const uint32_t card = vals.size(); const uint32_t nbits = bits.size(); off_t ierr = UnixWrite(fdes, &nrows, sizeof(uint32_t)); ierr += UnixWrite(fdes, &nbits, sizeof(uint32_t)); ierr += UnixWrite(fdes, &card, sizeof(uint32_t)); if (ierr < 12) { LOGGER(ibis::gVerbose > 0) << "Warning -- " << evt << " expects to write 3 4-byte words to " << fdes << ", but the number of byte wrote is " << ierr; (void) UnixSeek(fdes, start, SEEK_SET); return -6; } offset32.clear(); offset64.resize(nbits+1); offset64[0] = 8*((start+sizeof(uint32_t)*3+7)/8); ierr = UnixSeek(fdes, offset64[0], SEEK_SET); if (ierr != offset64[0]) { LOGGER(ibis::gVerbose > 0) << "Warning -- " << evt << " seek(" << fdes << ", " << offset64[0] << ", SEEK_SET) returned " << ierr; UnixSeek(fdes, start, SEEK_SET); return -7; } ierr = UnixWrite(fdes, vals.begin(), sizeof(double)*card); if (ierr < static_cast<off_t>(sizeof(double)*card)) { LOGGER(ibis::gVerbose > 0) << "Warning -- " << evt << " expected to write " << sizeof(double)*card << " bytes to file descriptor " << fdes << ", but actually wrote " << ierr; (void) UnixSeek(fdes, start, SEEK_SET); return -8; } offset64[0] += sizeof(double) * card + sizeof(int64_t) * nbits + sizeof(int64_t); ierr = UnixSeek(fdes, sizeof(int64_t)*(nbits+1), SEEK_CUR); if (ierr != offset64[0]) { LOGGER(ibis::gVerbose > 0) << "Warning -- " << evt << " attempting to seek to " << offset64[0] << " file descriptor " << fdes << " returned " << ierr; (void) UnixSeek(fdes, start, SEEK_SET); return -9; } ierr = UnixWrite(fdes, cnts.begin(), sizeof(uint32_t)*card); if (ierr < static_cast<off_t>(sizeof(uint32_t)*card)) { LOGGER(ibis::gVerbose > 0) << "Warning -- " << evt << " expected to write " << sizeof(int32_t)*card << " bytes to file descriptor " << fdes << ", but actually wrote " << ierr; (void) UnixSeek(fdes, start, SEEK_SET); return -10; } offset64[0] += sizeof(uint32_t)*card; for (uint32_t i = 0; i < nbits; ++i) { if (bits[i]) bits[i]->write(fdes); offset64[i+1] = UnixSeek(fdes, 0, SEEK_CUR); } const off_t offpos = 8*((start+sizeof(uint32_t)*3+7)/8)+sizeof(double)*card; ierr = UnixSeek(fdes, offpos, SEEK_SET); if (ierr != offpos) { LOGGER(ibis::gVerbose > 0) << "Warning -- " << evt << " seek(" << fdes << ", " << offpos << ", SEEK_SET) returned " << ierr; (void) UnixSeek(fdes, start, SEEK_SET); return -11; } ierr = UnixWrite(fdes, offset64.begin(), sizeof(int64_t)*(nbits+1)); if (ierr < static_cast<off_t>(sizeof(int64_t)*(nbits+1))) { LOGGER(ibis::gVerbose > 0) << "Warning -- " << evt << " expected to write " << sizeof(int64_t)*(nbits+1) << " bytes to file descriptor " << fdes << ", but actually wrote " << ierr; (void) UnixSeek(fdes, start, SEEK_SET); return -12; } ierr = UnixSeek(fdes, offset64.back(), SEEK_SET); return (ierr == offset64[nbits] ? 0 : -13); } // ibis::skive::write64
//! Process playback buffer. void AlsaBackend::CallbackOutputEvent(AudioStream* outputStream) { int result; DeviceSettings* device = static_cast<DeviceSettings*>(outputStream->callback.userdata); AlsaHandle *apiInfo = (AlsaHandle *)outputStream->apiHandle; snd_pcm_t *handle = (snd_pcm_t *)apiInfo->handle; apiInfo->xrun = false; snd_pcm_sframes_t samplesPer10ms = outputStream->spec.rate / 100; snd_pcm_sframes_t avail; while (outputStream->running && (apiInfo->type != DeviceInfo::TYPE_NULL)) { avail = alsa_safe_avail(handle, outputStream->spec.bufferFrames * outputStream->spec.FrameBytes(), outputStream->spec); if (avail < 0) { if ((result = HandleXrun(avail, 0, outputStream, "coe:alsa_safe_avail")) == 0) continue; return; } if (avail < samplesPer10ms) break; //printf("Filling up to %ld frames\n", avail); snd_pcm_sframes_t occupied = outputStream->buffer->Occupied(); if (occupied < samplesPer10ms) { size_t toFill; char* bufptr = outputStream->buffer->WriteBuf(toFill); if (toFill >= (size_t)samplesPer10ms) { outputStream->callback.callback((short*)bufptr, samplesPer10ms, device->spec.rate, device->spec.channels, device->userData); if (!outputStream->running) break; outputStream->buffer->Written(samplesPer10ms); } } size_t toWrite; char* bufptr = outputStream->buffer->ReadBuf(toWrite); toWrite = HandleXrun(UnixWrite(apiInfo, bufptr, toWrite), toWrite, outputStream, "UnixWrite"); if ((ssize_t)toWrite > 0) { outputStream->buffer->Read(toWrite); } if (apiInfo->first) { Log("Starting playback."); AlsaPrepareStart(handle); apiInfo->first = false; } } }