TAction* HashCreateXdbKeys(Transaction *t,
                           const char *hash_name,
                           const char *db_name)
{
  size_t existvar = t->MakeVariable();
  size_t keylistvar = t->MakeVariable();
  size_t keyvar = t->MakeVariable();

  TOperand *existarg = new TOperandVariable(t, existvar);
  TOperand *keylistarg = new TOperandVariable(t, keylistvar);
  TOperand *keyarg = new TOperandVariable(t, keyvar);

  TActionIterate *key_iter = new TActionIterate(t, keyvar, keylistarg);
  key_iter->PushAction(HashInsertKey(t, hash_name, keyarg));

  TActionTest *nex_test = new TActionTest(t, existarg, false);
  nex_test->PushAction(HashClear(t, hash_name));
  nex_test->PushAction(XdbAllKeys(t, db_name, keylistvar));
  nex_test->PushAction(key_iter);

  TActionSequence *sequence = new TActionSequence(t);
  sequence->PushAction(HashExists(t, hash_name, existvar));
  sequence->PushAction(nex_test);

  return sequence;
}
Exemplo n.º 2
0
// Add the node to the chain.  First we must verify that the chain
// is large enough for nArg; if not, grow it.  Than add it at
// the appropriate index.
status_t ArpIndexedList::pAddNode(ArpIndexedNode *node)
{
	long hash = HashForIndex(node->Index());
#if 0 	// why did I write this?  Isn't the POINT that if the hash is
		// too large, then the list grows?
	if (not HashExists(hash)) {
		delete node;
		return B_ERROR;
	}
#endif

	if (hash >= count) {
		GrowToAtLeast(hash + ARP_CHAIN_INCREMENT);	
	}

	if (chain[hash] == NULL) {
		chain[hash] = node;
		pAddNodeAtChainHead(node, hash);
	} else if (node->Index() < chain[hash]->Index()) {
		chain[hash]->AddNode(node);
		chain[hash] = node;
	} else {
		chain[hash]->AddNode(node);
	}
	
	// If the node is the new last node in the list then assign it
	// to the cached tailNode.
//	if ((tailNode == NULL) or (tailNode->Index() < node->Index()))
//		tailNode = node;

	AddedNode(node);
	return B_OK;
}
Exemplo n.º 3
0
status_t ArpIndexedList::NodeAfter(int32 index, ArpIndexedNode **answer,
						int32 findNode)
{
	long hash = HashForIndex(index);
	if (! HashExists(hash)) return B_ERROR;

	ArpIndexedNode	*nodeAfter = NULL,
					*node = NULL;
	node = NextChainHeadFrom(hash);

	// Find the first node on or after index.
	while (node != NULL) {
		if (node->Index() >= index) {
			nodeAfter = node;
			node = NULL;
		} else {
			node = node->next;
		}
	}
	if (nodeAfter == NULL) return B_ERROR;
	node = nodeAfter;

	// Now find whichever of the n nodes with the same index that
	// the client has requested.
	for (int32 k=0; k< findNode; k++) {
		node = node->next;
		if (node == NULL) return B_ERROR;
	}
	if (node->Index() != nodeAfter->Index()) return B_ERROR;
	*answer = node;
	return B_OK;
}
Exemplo n.º 4
0
ArpIndexedNode* ArpIndexedList::NextChainHeadFrom(int32 hash)
{
	int32	k = hash;
	while (HashExists(k)) {
		if (chain[k] != NULL) return chain[k];
		k++;
	}
	return NULL;
}
Exemplo n.º 5
0
void ArpIndexedList::SyncTailNode()
{
	for (int32 i=count-1; i>=0; i--) {
		if (! HashExists(i)) assert(false);
		if (chain[i] != 0) {
			tailNode = chain[i]->TailNode();
			return;
		}
	}
	tailNode = 0;
}
TAction* XdbClearIfNotHash(Transaction *t,
                           const char *dbname,
                           const char *hashname)
{
  size_t existvar = t->MakeVariable();
  TOperand *existarg = new TOperandVariable(t, existvar);

  TActionTest *nexist_test = new TActionTest(t, existarg, false);
  nexist_test->PushAction(XdbClear(t, dbname));

  TActionSequence *sequence = new TActionSequence(t);
  sequence->PushAction(HashExists(t, hashname, existvar));
  sequence->PushAction(nexist_test);

  return sequence;
}
Exemplo n.º 7
0
status_t ArpIndexedList::pRemoveNode(ArpIndexedNode *node)
{
	assert(node != 0);
	int32	hash = HashForIndex(node->Index());
	if (! HashExists(hash)) return B_ERROR;
	if (chain[hash] == 0) return B_ERROR;

	if (node == chain[hash]) {
		status_t	answer;
		ArpIndexedNode	*unusedVar;
		answer = pRemoveChainHeadAt(hash, &unusedVar);
		if (answer != B_OK) return answer;
	}

	RemovingNode(node);
	node->RemoveNode();
	RemovedNode(node);
	return B_OK;
}
Exemplo n.º 8
0
status_t ArpIndexedList::ChainHeadFrom(int32 index, ArpIndexedNode **node) {
	long hash = HashForIndex(index);

	// We used to hash to 1 minus the hash of the index, but we've removed that.
	// If clients want that, they can send it themselves.
	*node = 0;
	while (*node == 0) {
		if (! HashExists(hash)) return B_ERROR;
		*node = chain[hash];
		hash++;
	}
	return B_OK;
#if 0
	*node = chain[hash];
printf("ArpIndexedList::ChainHeadFrom() 5\n");  fflush(stdout);
Print();
	if (*node == 0) return B_ERROR;
	return B_OK;
#endif
}
Exemplo n.º 9
0
status_t ArpIndexedList::NodeBefore(int32 index, ArpIndexedNode **answer,
						int32 findNode)
{
	long hash = HashForIndex(index);
	if (hash >= count) hash = count - 1;
	if (! HashExists(hash)) return B_ERROR;

	ArpIndexedNode	*nodeBefore = 0,
					*node = 0;
	
	// Find the first chain before the index that isn't NULL
	bool		keepLooking = true;
	for (int32 k = hash; keepLooking; k--) {
		if (! HashExists(k)) {
			keepLooking = false;
		} else if ( (chain[k] != 0) && (chain[k]->Index() <= index) ) {
			node = chain[k];
			keepLooking = false;
		}
	}
	if (node == 0) return B_ERROR;

	// Find the first node on or before index.
	while (node != 0) {
		if (node->next == 0) {
			nodeBefore = node;
			node = 0;
		} else if (node->Index() == index) {
			nodeBefore = node;
			node = 0;
		} else if (node->next->Index() == index) {
			nodeBefore = node->next;
			node = 0;
		} else if ( (node->Index() <= index)
				&& (node->next->Index() >= index) ) {
			nodeBefore = node;
			node = 0;
		} else {
			node = node->next;
		}
	}
	if (nodeBefore == 0) return B_ERROR;
	node = nodeBefore;

	// The above routines might put us on the last node in a
	// series of nodes with the same index -- no real way around
	// that, I don't think.  If that's the case, rewind us back
	// to the first node.
	while ( (node->prev != 0)
			&& (node->prev->Index() == node->Index()) )
		node = node->prev;

	// Now find whichever of the n nodes with the same index that
	// the client has requested.
	for (int32 k=1; k<= findNode; k++) {
		node = node->next;
		if (node == 0) return B_ERROR;
	}
	if (node->Index() != nodeBefore->Index()) return B_ERROR;
	*answer = node;
	return B_OK;
}
Exemplo n.º 10
0
int32 ArpIndexedList::IndexHeadFrom(int32 index)
{
	long hash = HashForIndex(index);
	if (! HashExists(hash)) return B_ERROR;
	return hash * ChainIndexes();
}