Beispiel #1
0
// 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
Beispiel #2
0
/// 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;
        }
    }
}