Пример #1
0
 string longestCommonPrefix(vector<string>& strs) {
     if (strs.size() == 0) return "";
     else if (strs.size() == 1) return strs[0];
     
     string cmPrefix = commonPrefix(strs[0], strs[1]);
     
     for (int i = 1; i < strs.size(); ++i) {
         cmPrefix = commonPrefix(cmPrefix, strs[i]);
     }
     return cmPrefix;
 }
Пример #2
0
int
TSHPath::CommonPrefix(LPCTSTR pszFile1, LPCTSTR pszFile2, LPTSTR achPath)
{
  static TModuleProc3<int,LPCTSTR,LPCTSTR,LPTSTR>
         commonPrefix(GetModule(), CommonPrefixStr);
  return commonPrefix(pszFile1, pszFile2, achPath);
}
Пример #3
0
 string longestCommonPrefix(vector<string>& strs,int left,int right) {
     if(left == right){
         return strs[left];
     }
     int mid = left + (right-left)/2;
     string lstr = longestCommonPrefix(strs,left,mid);
     string rstr = longestCommonPrefix(strs,mid+1,right);
     return commonPrefix(lstr,rstr);
 }
    string longestCommonPrefix(vector<string>& strs) {
        string res;
        if(strs.size() == 0)
            return res;

        res = strs[0];
        for(unsigned int index = 1; index < strs.size(); index++){
            commonPrefix(strs[index],res);
        }

        return res;
    }
Пример #5
0
UTILS_EXPORT QString commonPath(const QStringList &files)
{
    QString common = commonPrefix(files);
    // Find common directory part: "C:\foo\bar" -> "C:\foo"
    int lastSeparatorPos = common.lastIndexOf(QLatin1Char('/'));
    if (lastSeparatorPos == -1)
        lastSeparatorPos = common.lastIndexOf(QLatin1Char('\\'));
    if (lastSeparatorPos == -1)
        return QString();
    if (HostOsInfo::isAnyUnixHost() && lastSeparatorPos == 0) // Unix: "/a", "/b" -> '/'
        lastSeparatorPos = 1;
    common.truncate(lastSeparatorPos);
    return common;
}
Пример #6
0
QTCREATOR_UTILS_EXPORT QString commonPath(const QStringList &files)
{
    QString common = commonPrefix(files);
    // Find common directory part: "C:\foo\bar" -> "C:\foo"
    int lastSeparatorPos = common.lastIndexOf(QLatin1Char('/'));
    if (lastSeparatorPos == -1)
        lastSeparatorPos = common.lastIndexOf(QLatin1Char('\\'));
    if (lastSeparatorPos == -1)
        return QString();
#ifdef Q_OS_UNIX
    if (lastSeparatorPos == 0) // Unix: "/a", "/b" -> '/'
        lastSeparatorPos = 1;
#endif
    common.truncate(lastSeparatorPos);
    return common;
}
Пример #7
0
MemTrieNode* MemTrieNode::newBranch(bytesConstRef _k1, std::string const& _v1, bytesConstRef _k2, std::string const& _v2)
{
	unsigned prefix = commonPrefix(_k1, _k2);

	MemTrieNode* ret;
	if (_k1.size() == prefix)
		ret = new TrieBranchNode(_k2[prefix], new TrieLeafNode(_k2.cropped(prefix + 1), _v2), _v1);
	else if (_k2.size() == prefix)
		ret = new TrieBranchNode(_k1[prefix], new TrieLeafNode(_k1.cropped(prefix + 1), _v1), _v2);
	else // both continue after split
		ret = new TrieBranchNode(_k1[prefix], new TrieLeafNode(_k1.cropped(prefix + 1), _v1), _k2[prefix], new TrieLeafNode(_k2.cropped(prefix + 1), _v2));

	if (prefix)
		// have shared prefix - split.
		ret = new TrieInfixNode(_k1.cropped(0, prefix), ret);

	return ret;
}
Пример #8
0
MemTrieNode* TrieInfixNode::insert(bytesConstRef _key, std::string const& _value)
{
	assert(_value.size());
	mark();
	if (contains(_key))
	{
		m_next = m_next->insert(_key.cropped(m_ext.size()), _value);
		return this;
	}
	else
	{
		unsigned prefix = commonPrefix(_key, m_ext);
		if (prefix)
		{
			// one infix becomes two infixes, then insert into the second
			// instead of pop_front()...
			trimFront(m_ext, prefix);

			return new TrieInfixNode(_key.cropped(0, prefix), insert(_key.cropped(prefix), _value));
		}
		else
		{
			// split here.
			auto f = m_ext[0];
			trimFront(m_ext, 1);
			MemTrieNode* n = m_ext.empty() ? m_next : this;
			if (n != this)
			{
				m_next = nullptr;
				delete this;
			}
			TrieBranchNode* ret = new TrieBranchNode(f, n);
			ret->insert(_key, _value);
			return ret;
		}
	}
}
Пример #9
0
Datum
spg_text_picksplit(PG_FUNCTION_ARGS)
{
    spgPickSplitIn *in = (spgPickSplitIn *) PG_GETARG_POINTER(0);
    spgPickSplitOut *out = (spgPickSplitOut *) PG_GETARG_POINTER(1);
    text	   *text0 = DatumGetTextPP(in->datums[0]);
    int			i,
                commonLen;
    spgNodePtr *nodes;

    /* Identify longest common prefix, if any */
    commonLen = VARSIZE_ANY_EXHDR(text0);
    for (i = 1; i < in->nTuples && commonLen > 0; i++)
    {
        text	   *texti = DatumGetTextPP(in->datums[i]);
        int			tmp = commonPrefix(VARDATA_ANY(text0),
                                       VARDATA_ANY(texti),
                                       VARSIZE_ANY_EXHDR(text0),
                                       VARSIZE_ANY_EXHDR(texti));

        if (tmp < commonLen)
            commonLen = tmp;
    }

    /*
     * Limit the prefix length, if necessary, to ensure that the resulting
     * inner tuple will fit on a page.
     */
    commonLen = Min(commonLen, SPGIST_MAX_PREFIX_LENGTH);

    /* Set node prefix to be that string, if it's not empty */
    if (commonLen == 0)
    {
        out->hasPrefix = false;
    }
    else
    {
        out->hasPrefix = true;
        out->prefixDatum = formTextDatum(VARDATA_ANY(text0), commonLen);
    }

    /* Extract the node label (first non-common byte) from each value */
    nodes = (spgNodePtr *) palloc(sizeof(spgNodePtr) * in->nTuples);

    for (i = 0; i < in->nTuples; i++)
    {
        text	   *texti = DatumGetTextPP(in->datums[i]);

        if (commonLen < VARSIZE_ANY_EXHDR(texti))
            nodes[i].c = *(uint8 *) (VARDATA_ANY(texti) + commonLen);
        else
            nodes[i].c = '\0';			/* use \0 if string is all common */
        nodes[i].i = i;
        nodes[i].d = in->datums[i];
    }

    /*
     * Sort by label bytes so that we can group the values into nodes.  This
     * also ensures that the nodes are ordered by label value, allowing the
     * use of binary search in searchChar.
     */
    qsort(nodes, in->nTuples, sizeof(*nodes), cmpNodePtr);

    /* And emit results */
    out->nNodes = 0;
    out->nodeLabels = (Datum *) palloc(sizeof(Datum) * in->nTuples);
    out->mapTuplesToNodes = (int *) palloc(sizeof(int) * in->nTuples);
    out->leafTupleDatums = (Datum *) palloc(sizeof(Datum) * in->nTuples);

    for (i = 0; i < in->nTuples; i++)
    {
        text	   *texti = DatumGetTextPP(nodes[i].d);
        Datum		leafD;

        if (i == 0 || nodes[i].c != nodes[i - 1].c)
        {
            out->nodeLabels[out->nNodes] = UInt8GetDatum(nodes[i].c);
            out->nNodes++;
        }

        if (commonLen < VARSIZE_ANY_EXHDR(texti))
            leafD = formTextDatum(VARDATA_ANY(texti) + commonLen + 1,
                                  VARSIZE_ANY_EXHDR(texti) - commonLen - 1);
        else
            leafD = formTextDatum(NULL, 0);

        out->leafTupleDatums[nodes[i].i] = leafD;
        out->mapTuplesToNodes[nodes[i].i] = out->nNodes - 1;
    }

    PG_RETURN_VOID();
}
Пример #10
0
Datum
spg_text_choose(PG_FUNCTION_ARGS)
{
    spgChooseIn *in = (spgChooseIn *) PG_GETARG_POINTER(0);
    spgChooseOut *out = (spgChooseOut *) PG_GETARG_POINTER(1);
    text	   *inText = DatumGetTextPP(in->datum);
    char	   *inStr = VARDATA_ANY(inText);
    int			inSize = VARSIZE_ANY_EXHDR(inText);
    uint8		nodeChar = '\0';
    int			i = 0;
    int			commonLen = 0;

    /* Check for prefix match, set nodeChar to first byte after prefix */
    if (in->hasPrefix)
    {
        text	   *prefixText = DatumGetTextPP(in->prefixDatum);
        char	   *prefixStr = VARDATA_ANY(prefixText);
        int			prefixSize = VARSIZE_ANY_EXHDR(prefixText);

        commonLen = commonPrefix(inStr + in->level,
                                 prefixStr,
                                 inSize - in->level,
                                 prefixSize);

        if (commonLen == prefixSize)
        {
            if (inSize - in->level > commonLen)
                nodeChar = *(uint8 *) (inStr + in->level + commonLen);
            else
                nodeChar = '\0';
        }
        else
        {
            /* Must split tuple because incoming value doesn't match prefix */
            out->resultType = spgSplitTuple;

            if (commonLen == 0)
            {
                out->result.splitTuple.prefixHasPrefix = false;
            }
            else
            {
                out->result.splitTuple.prefixHasPrefix = true;
                out->result.splitTuple.prefixPrefixDatum =
                    formTextDatum(prefixStr, commonLen);
            }
            out->result.splitTuple.nodeLabel =
                UInt8GetDatum(*(prefixStr + commonLen));

            if (prefixSize - commonLen == 1)
            {
                out->result.splitTuple.postfixHasPrefix = false;
            }
            else
            {
                out->result.splitTuple.postfixHasPrefix = true;
                out->result.splitTuple.postfixPrefixDatum =
                    formTextDatum(prefixStr + commonLen + 1,
                                  prefixSize - commonLen - 1);
            }

            PG_RETURN_VOID();
        }
    }
    else if (inSize > in->level)
    {
        nodeChar = *(uint8 *) (inStr + in->level);
    }
    else
    {
        nodeChar = '\0';
    }

    /* Look up nodeChar in the node label array */
    if (searchChar(in->nodeLabels, in->nNodes, nodeChar, &i))
    {
        /*
         * Descend to existing node.  (If in->allTheSame, the core code will
         * ignore our nodeN specification here, but that's OK.  We still
         * have to provide the correct levelAdd and restDatum values, and
         * those are the same regardless of which node gets chosen by core.)
         */
        out->resultType = spgMatchNode;
        out->result.matchNode.nodeN = i;
        out->result.matchNode.levelAdd = commonLen + 1;
        if (inSize - in->level - commonLen - 1 > 0)
            out->result.matchNode.restDatum =
                formTextDatum(inStr + in->level + commonLen + 1,
                              inSize - in->level - commonLen - 1);
        else
            out->result.matchNode.restDatum =
                formTextDatum(NULL, 0);
    }
    else if (in->allTheSame)
    {
        /*
         * Can't use AddNode action, so split the tuple.  The upper tuple
         * has the same prefix as before and uses an empty node label for
         * the lower tuple.  The lower tuple has no prefix and the same
         * node labels as the original tuple.
         */
        out->resultType = spgSplitTuple;
        out->result.splitTuple.prefixHasPrefix = in->hasPrefix;
        out->result.splitTuple.prefixPrefixDatum = in->prefixDatum;
        out->result.splitTuple.nodeLabel = UInt8GetDatum('\0');
        out->result.splitTuple.postfixHasPrefix = false;
    }
    else
    {
        /* Add a node for the not-previously-seen nodeChar value */
        out->resultType = spgAddNode;
        out->result.addNode.nodeLabel = UInt8GetDatum(nodeChar);
        out->result.addNode.nodeN = i;
    }

    PG_RETURN_VOID();
}
Пример #11
0
Datum
spg_text_choose(PG_FUNCTION_ARGS)
{
	spgChooseIn *in = (spgChooseIn *) PG_GETARG_POINTER(0);
	spgChooseOut *out = (spgChooseOut *) PG_GETARG_POINTER(1);
	text	   *inText = DatumGetTextPP(in->datum);
	char	   *inStr = VARDATA_ANY(inText);
	int			inSize = VARSIZE_ANY_EXHDR(inText);
	char	   *prefixStr = NULL;
	int			prefixSize = 0;
	int			commonLen = 0;
	int16		nodeChar = 0;
	int			i = 0;

	/* Check for prefix match, set nodeChar to first byte after prefix */
	if (in->hasPrefix)
	{
		text	   *prefixText = DatumGetTextPP(in->prefixDatum);

		prefixStr = VARDATA_ANY(prefixText);
		prefixSize = VARSIZE_ANY_EXHDR(prefixText);

		commonLen = commonPrefix(inStr + in->level,
								 prefixStr,
								 inSize - in->level,
								 prefixSize);

		if (commonLen == prefixSize)
		{
			if (inSize - in->level > commonLen)
				nodeChar = *(unsigned char *) (inStr + in->level + commonLen);
			else
				nodeChar = -1;
		}
		else
		{
			/* Must split tuple because incoming value doesn't match prefix */
			out->resultType = spgSplitTuple;

			if (commonLen == 0)
			{
				out->result.splitTuple.prefixHasPrefix = false;
			}
			else
			{
				out->result.splitTuple.prefixHasPrefix = true;
				out->result.splitTuple.prefixPrefixDatum =
					formTextDatum(prefixStr, commonLen);
			}
			out->result.splitTuple.nodeLabel =
				Int16GetDatum(*(unsigned char *) (prefixStr + commonLen));

			if (prefixSize - commonLen == 1)
			{
				out->result.splitTuple.postfixHasPrefix = false;
			}
			else
			{
				out->result.splitTuple.postfixHasPrefix = true;
				out->result.splitTuple.postfixPrefixDatum =
					formTextDatum(prefixStr + commonLen + 1,
								  prefixSize - commonLen - 1);
			}

			PG_RETURN_VOID();
		}
	}
	else if (inSize > in->level)
	{
		nodeChar = *(unsigned char *) (inStr + in->level);
	}
	else
	{
		nodeChar = -1;
	}

	/* Look up nodeChar in the node label array */
	if (searchChar(in->nodeLabels, in->nNodes, nodeChar, &i))
	{
		/*
		 * Descend to existing node.  (If in->allTheSame, the core code will
		 * ignore our nodeN specification here, but that's OK.  We still have
		 * to provide the correct levelAdd and restDatum values, and those are
		 * the same regardless of which node gets chosen by core.)
		 */
		int			levelAdd;

		out->resultType = spgMatchNode;
		out->result.matchNode.nodeN = i;
		levelAdd = commonLen;
		if (nodeChar >= 0)
			levelAdd++;
		out->result.matchNode.levelAdd = levelAdd;
		if (inSize - in->level - levelAdd > 0)
			out->result.matchNode.restDatum =
				formTextDatum(inStr + in->level + levelAdd,
							  inSize - in->level - levelAdd);
		else
			out->result.matchNode.restDatum =
				formTextDatum(NULL, 0);
	}
	else if (in->allTheSame)
	{
		/*
		 * Can't use AddNode action, so split the tuple.  The upper tuple has
		 * the same prefix as before and uses a dummy node label -2 for the
		 * lower tuple.  The lower tuple has no prefix and the same node
		 * labels as the original tuple.
		 *
		 * Note: it might seem tempting to shorten the upper tuple's prefix,
		 * if it has one, then use its last byte as label for the lower tuple.
		 * But that doesn't win since we know the incoming value matches the
		 * whole prefix: we'd just end up splitting the lower tuple again.
		 */
		out->resultType = spgSplitTuple;
		out->result.splitTuple.prefixHasPrefix = in->hasPrefix;
		out->result.splitTuple.prefixPrefixDatum = in->prefixDatum;
		out->result.splitTuple.nodeLabel = Int16GetDatum(-2);
		out->result.splitTuple.postfixHasPrefix = false;
	}
	else
	{
		/* Add a node for the not-previously-seen nodeChar value */
		out->resultType = spgAddNode;
		out->result.addNode.nodeLabel = Int16GetDatum(nodeChar);
		out->result.addNode.nodeN = i;
	}

	PG_RETURN_VOID();
}
Пример #12
0
/// <summary>
/// Generates the hierarchy.  http://devblogs.nvidia.com/parallelforall/wp-content/uploads/sites/3/2012/11/karras2012hpg_paper.pdf
/// </summary>
/// <param name="boxes">The boxes.</param>
void BVH::generateHierarchyFullParallel(std::vector<AABBox>& boxes)
{
	ProgressBar progressBar;

#if !_DEBUG
#pragma omp parallel for schedule(dynamic,1)
#endif
	for (int i = 0; i < (boxes.size() - 1); i++)
	{
		//first, find the range this node corresponds to
		//d == -1 means range ends at i, d == +1 means range starts at i
		int d = sign(commonPrefix(boxes, i, i + 1) - commonPrefix(boxes, i, i - 1));

		//find a maximum and minimum value for the range this node covers.  Must be a power of two for easy binary searching
		int min = commonPrefix(boxes, i, i - d);
		int max = 128;

		while (commonPrefix(boxes, i, i + (max * d)) > min)
		{
			max *= 4;
		}

		//use binary serach to find the farthest common prefis that is greater than min
		int l = 0;
		for (int t = max >> 1; t >= 1; t = t >> 1)
		{
			if (commonPrefix(boxes, i, i + (l + t) * d) > min)
			{
				//serach to the right of this value
				l += t;
			}
		}

		//end of range
		int j = i + l * d;
		int first = i;

		if (d < 0)
		{
			first = j;
			j = i;
		}


		// Determine where to split the range.
		int split = findSplit(boxes, first, j);

		Node* rightChild;
		if (split == first)
		{
			rightChild = &m_leafNodes[split];
		}
		else
		{
			rightChild = &m_branchNodes[split];
		}

		Node* leftChild;
		if (split + 1 == j)
		{
			leftChild = &m_leafNodes[split + 1];
		}
		else
		{
			leftChild = &m_branchNodes[split + 1];
		}

//		m_branchNodes[i].m = max;
//		m_branchNodes[i].re = first;
//		m_branchNodes[i].rs = j;
//		m_branchNodes[i].s = split;
		m_branchNodes[i].rightChild = rightChild;
		m_branchNodes[i].leftChild = leftChild;
//		leftChild->parent = &m_branchNodes[i];
//		rightChild->parent = &m_branchNodes[i];

#pragma omp critical
		{
			progressBar.updateProgress(static_cast<int>((static_cast<float>(i) / boxes.size()) * 100));
		}
	}

	progressBar.end();
}