Beispiel #1
0
//
// insert
//
bool BPlusNode::insert(int idx, KeyPtr key, const RID& rid)
{
	if ((idx < 0) || (idx > size_)) return false;
	int count = size_  - idx;
	memmove(keyAt(idx + 1), keyAt(idx), count * len_);
	memmove(&rids_[idx + 1], &rids_[idx], count * sizeof(RID));
	memcpy(keyAt(idx), key, len_);
	updateRid(idx, rid);
	size_++;
	setSize(size_);
	page_.setDirty();
	return true;
}
Beispiel #2
0
bool BPlusNode::erase(int idx)
{
	if ((idx < 0) || (idx >= size_)) return false;
	int size = size_ - idx - 1;
	if (idx != size_ - 1) {
		memmove(keyAt(idx), keyAt(idx + 1), size * len_);
		memmove(&rids_[idx], &rids_[idx + 1], size * sizeof(RID));
	}
	size_--;
	setSize(size_);
	page_.setDirty();
	return true;
}
Beispiel #3
0
//
// leftmostSearchPos - 从左到右最后一个比key小的数的下标,如果都大于key的话,返回-1
//
int BPlusNode::leftmostSearchPos(KeyPtr key)
{
	int pos = 0;
	int begin = 0, end = size_ - 1;
	while (begin <= end) {
		int mid = (begin + end) / 2;
		KeyPtr k = keyAt(mid);
		int res = keyComp(k, key);
		if (res < 0) begin = mid + 1;
		else if (res > 0) end = mid - 1;
		else end = mid - 1;
	}
	if (begin >= size_) return size_ - 1;
	if (begin == 0) return keyComp(keyAt(0), key) > 0 ? -1 : 0;
	return begin - 1;
}
Beispiel #4
0
int BPlusNode::search(KeyPtr key, const RID &rid)
{
	int low = lowerBound(key);
	if (low < 0) return -1;
	for (int i = low; i < size_; i++) {
		if (keyComp(keyAt(i), key) != 0) break;
		if (rids_[i] == rid) return i;
	}
	return -1;
}
Beispiel #5
0
        /* Since the last noteLocation(), our key may have moved around, and that old cached
           information may thus be stale and wrong (although often it is right).  We check
           that here; if we have moved, we have to search back for where we were at.

           i.e., after operations on the index, the BtreeCursor's cached location info may
           be invalid.  This function ensures validity, so you should call it before using
           the cursor if other writers have used the database since the last noteLocation
           call.
        */
        void checkLocation() {
            if ( eof() )
                return;

            _multikey = d->isMultikey(idxNo);

            if ( keyOfs >= 0 ) {
                assert( !keyAtKeyOfs.isEmpty() );

                try {
                    // Note keyAt() returns an empty BSONObj if keyOfs is now out of range,
                    // which is possible as keys may have been deleted.
                    int x = 0;
                    while( 1 ) {
                        //  if ( b->keyAt(keyOfs).woEqual(keyAtKeyOfs) &&
                        //       b->k(keyOfs).recordLoc == locAtKeyOfs ) {
                        if ( keyAt(keyOfs).binaryEqual(keyAtKeyOfs) ) {
                            const _KeyNode& kn = keyNode(keyOfs);
                            if( kn.recordLoc == locAtKeyOfs ) {
                                if ( !kn.isUsed() ) {
                                    // we were deleted but still exist as an unused
                                    // marker key. advance.
                                    skipUnusedKeys();
                                }
                                return;
                            }
                        }

                        // we check one key earlier too, in case a key was just deleted.  this is
                        // important so that multi updates are reasonably fast.
                        if( keyOfs == 0 || x++ )
                            break;
                        keyOfs--;
                    }
                }
                catch(UserException& e) { 
                    if( e.getCode() != 15850 )
                        throw;
                    // hack: fall through if bucket was just deleted. should only happen under deleteObjects()
                    DEV log() << "debug info: bucket was deleted" << endl;
                }
            }

            /* normally we don't get to here.  when we do, old position is no longer
                valid and we must refind where we left off (which is expensive)
            */

            /* TODO: Switch to keep indexdetails and do idx.head! */
            bucket = _locate(keyAtKeyOfs, locAtKeyOfs);
            RARELY log() << "key seems to have moved in the index, refinding. " << bucket.toString() << endl;
            if ( ! bucket.isNull() )
                skipUnusedKeys();

        }
Beispiel #6
0
//
// lowerBound - 在本node节点的寻找和key一致的最左边的键的下标
//
int BPlusNode::lowerBound(KeyPtr key)
{
	KeyPtr k;
	int begin = 0, end = size_ - 1;
	while (begin <= end) {
		int mid = (begin + end) / 2;
		k = keyAt(mid);
		int res = keyComp(k, key);
		if (res < 0) {
			begin = mid + 1;
		}
		else if (res > 0) {
			end = mid - 1;
		} 
		else { // k == key
			end = mid - 1;
		}
	}
	if (begin >= size_) return -1;
	return keyComp(keyAt(begin), key) == 0 ? begin : -1;
}
Beispiel #7
0
int SymbolInfoJob::execute()
{
    int ret = 1;
    int idx = -1;
    if (end.isNull()) {
        auto symbol = project()->findSymbol(start, &idx);
        if (!symbol.isNull()) {
            write(symbol);
            ret = 0;
        }
    } else {
        assert(start.fileId() == end.fileId());
        auto symbols = project()->openSymbols(start.fileId());
        if (symbols && symbols->count()) {
            bool exact = false;
            uint32_t idx = symbols->lowerBound(start, &exact);
            if (exact) {
                write("(list");
                write(symbols->valueAt(idx++));
                ret = 0;
            } else {
                switch (idx) {
                case 0:
                    break;
                case std::numeric_limits<uint32_t>::max():
                    idx = symbols->count() - 1;
                    break;
                default:
                    --idx;
                    break;
                }
            }
            const uint32_t count = symbols->count();
            while (idx < count) {
                const Location loc = symbols->keyAt(idx);
                if (loc > end)
                    break;
                if (loc >= start) {
                    if (ret)
                        write("(list");
                    write(symbols->valueAt(idx));
                    ret = 0;
                }
                ++idx;
            }
            if (!ret)
                write(")");
        }
    }
    return ret;
}
Beispiel #8
0
status_t SwAudioOutputCollection::dump(int fd) const
{
    const size_t SIZE = 256;
    char buffer[SIZE];

    snprintf(buffer, SIZE, "\nOutputs dump:\n");
    write(fd, buffer, strlen(buffer));
    for (size_t i = 0; i < size(); i++) {
        snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i));
        write(fd, buffer, strlen(buffer));
        valueAt(i)->dump(fd);
    }

    return NO_ERROR;
}
Beispiel #9
0
//
// insert - 将一个索引的item装入Node里面
// 
bool BPlusNode::insert(const KeyPtr key, const RID& rid)
{
	int i = -1;
	KeyPtr prev = nullptr, curr = nullptr;
	// 从后往前扫描
	for (i = size_ - 1; i >= 0; i--)
	{
		prev = curr;
		curr = keyAt(i);
		if (keyComp(key, curr) > 0) break;
		rids_[i + 1] = rids_[i];
		updateKey(i + 1, curr);
	}
	rids_[i + 1] = rid;
	updateKey(i + 1, key);
	size_++;
	setSize(size_);
	page_.setDirty();
	return true;
}
Beispiel #10
0
//
// leftmostInsertPos - 查找key在最左侧的插入位置
//
int BPlusNode::leftmostInsertPos(KeyPtr key)
{
	int pos = 0;
	KeyPtr k;
	int begin = 0, end = size_ - 1;
	while (begin <= end) {
		int mid = (begin + end) / 2;
		k = keyAt(mid);
		int res = keyComp(k, key);
		if (res < 0) {
			begin = mid + 1;
		}
		else if (res > 0) {
			end = mid - 1;
		}
		else { // k == key
			end = mid - 1;
		}
	}
	return end + 1;
}
Beispiel #11
0
void BPlusNode::copyKey(int idx, KeyPtr key)
{
	KeyPtr src = keyAt(idx);
	memcpy(key, src, len_);
}
Beispiel #12
0
int StatusJob::execute()
{
    auto match = [this](const char *name) {
        return !strncasecmp(query.constData(), name, query.size());
    };
    bool matched = false;
    const char *alternatives = "fileids|watchedpaths|dependencies|cursors|symbols|targets|symbolnames|sources|jobs|info|compilers|headererrors|memory";

    if (match("fileids")) {
        matched = true;
        if (!write(delimiter) || !write("fileids") || !write(delimiter))
            return 1;
        const Hash<uint32_t, Path> paths = Location::idsToPaths();
        for (Hash<uint32_t, Path>::const_iterator it = paths.begin(); it != paths.end(); ++it) {
            if (!write<256>("  %u: %s", it->first, it->second.constData()))
                return 1;
        }
        if (isAborted())
            return 1;
    }

    if (match("headererrors")) {
        matched = true;
        if (!write(delimiter) || !write("headererrors") || !write(delimiter))
            return 1;
        for (auto err : Server::instance()->jobScheduler()->headerErrors()) {
            if (!write(Location::path(err)))
                return 1;
        }
        if (isAborted())
            return 1;
    }

    if (query.isEmpty() || match("info")) {
        matched = true;
        if (!write(delimiter) || !write("info") || !write(delimiter))
            return 1;
        String out;
        Log log(&out);
#ifdef NDEBUG
        out << "Running a release build\n";
#else
        out << "Running a debug build\n";
#endif
        const Server::Options &opt = Server::instance()->options();
        out << "socketFile" << opt.socketFile << '\n'
            << "dataDir" << opt.dataDir << '\n'
            << "options" << opt.options
            << "jobCount" << opt.jobCount << '\n'
            << "rpVisitFileTimeout" << opt.rpVisitFileTimeout << '\n'
            << "rpIndexDataMessageTimeout" << opt.rpIndexDataMessageTimeout << '\n'
            << "rpConnectTimeout" << opt.rpConnectTimeout << '\n'
            << "rpConnectTimeout" << opt.rpConnectTimeout << '\n'
            << "threadStackSize" << opt.threadStackSize << '\n'
            << "defaultArguments" << opt.defaultArguments << '\n'
            << "includePaths" << opt.includePaths << '\n'
            << "defines" << opt.defines << '\n'
            << "ignoredCompilers" << opt.ignoredCompilers;
        write(out);
    }


    std::shared_ptr<Project> proj = project();
    if (!proj) {
        if (!matched)
            write(alternatives);
        return matched ? 0 : 1;
    }

    if (query.isEmpty() || match("watchedpaths")) {
        matched = true;
        if (!write(delimiter) || !write("watchedpaths") || !write(delimiter))
            return 1;
        Hash<Path, Flags<Project::WatchMode> > watched = proj->watchedPaths();
        auto watchModeToString = [](Flags<Project::WatchMode> mode) {
            List<String> ret;
            if (mode & Project::Watch_FileManager)
                ret << "filemanager";
            if (mode & Project::Watch_SourceFile)
                ret << "source";
            if (mode & Project::Watch_Dependency)
                ret << "dependency";
            if (mode & Project::Watch_CompilationDatabase)
                ret << "compilationdatabase";
            return String::join(ret, '|');
        };
        for (const auto &it : watched) {
            if (!write<256>("  %s (%s)", it.first.constData(), watchModeToString(it.second).constData())) {
                return 1;
            }
        }
    }

    const Dependencies &deps = proj->dependencies();
    if (query.isEmpty() || match("dependencies")) {
        matched = true;
        if (!write(delimiter) || !write("dependencies") || !write(delimiter))
            return 1;

        for (auto it : deps) {
            write(proj->dumpDependencies(it.first));
        }
        if (isAborted())
            return 1;
    }

    if (query.isEmpty() || match("symbols") || match("cursors")) {
        matched = true;
        write(delimiter);
        write("symbols");
        write(delimiter);

        for (const auto &dep : deps) {
            auto symbols = proj->openSymbols(dep.first);
            if (!symbols)
                continue;
            const int count = symbols->count();
            for (int i=0; i<count; ++i) {
                const Location loc = symbols->keyAt(i);
                const Symbol c = symbols->valueAt(i);
                write(loc);
                write(c);
                write("------------------------");
                if (isAborted())
                    return 1;
            }
        }
    }

    if (query.isEmpty() || match("targets")) {
        matched = true;
        write(delimiter);
        write("targets");
        write(delimiter);
        for (const auto &dep : deps) {
            auto targets = proj->openTargets(dep.first);
            if (!targets)
                continue;
            const int count = targets->count();
            for (int i=0; i<count; ++i) {
                const String usr = targets->keyAt(i);
                write<128>("  %s", usr.constData());
                for (const auto &t : proj->findByUsr(usr, dep.first, Project::ArgDependsOn)) {
                    write<1024>("      %s\t%s", t.location.toString(locationToStringFlags()).constData(),
                                t.kindSpelling().constData());
                }
                for (const auto &location : targets->valueAt(i)) {
                    write<1024>("    %s", location.toString(locationToStringFlags()).constData());
                }
                write("------------------------");
                if (isAborted())
                    return 1;
            }
        }
    }

    if (query.isEmpty() || match("symbolnames")) {
        matched = true;
        write(delimiter);
        write("symbolnames");
        write(delimiter);
        for (const auto &dep : deps) {
            auto symNames = proj->openSymbolNames(dep.first);
            if (!symNames)
                continue;
            const int count = symNames->count();
            for (int i=0; i<count; ++i) {
                write<128>("  %s", symNames->keyAt(i).constData());
                for (const Location &loc : symNames->valueAt(i)) {
                    write<1024>("    %s", loc.toString().constData());
                }
                write("------------------------");
                if (isAborted())
                    return 1;
            }
        }
    }

    if (query.isEmpty() || match("sources")) {
        matched = true;
        const Sources &map = proj->sources();
        if (!write(delimiter) || !write("sources") || !write(delimiter))
            return 1;
        for (Sources::const_iterator it = map.begin(); it != map.end(); ++it) {
            if (!write<512>("  %s: %s", it->second.sourceFile().constData(), it->second.toString().constData()))
                return 1;
        }
    }

    if (query.isEmpty() || match("jobs")) {
        matched = true;
        if (!write(delimiter) || !write("jobs") || !write(delimiter))
            return 1;
        Server::instance()->dumpJobs(connection());
    }

    if (query.isEmpty() || match("compilers")) {
        matched = true;
        if (!write(delimiter) || !write("compilers") || !write(delimiter))
            return 1;
        Source source;
        for (const Path &compiler : CompilerManager::compilers()) {
            source.compilerId = Location::insertFile(compiler);
            source.defines.clear();
            source.includePaths.clear();
            CompilerManager::applyToSource(source, true, true);
            write(compiler);
            write("  Defines:");
            for (const auto &it : source.defines)
                write<512>("    %s", it.toString().constData());
            write("  Includepaths:");
            for (const auto &it : source.includePaths)
                write<512>("    %s", it.toString().constData());
            write("");
        }
    }

    if (query.isEmpty() || match("memory")) {
        write(proj->estimateMemory());
        matched = true;
    }


    if (!matched) {
        write<256>("rc -s %s", alternatives);
        return 1;
    } else {
        return 0;
    }
}