Ejemplo n.º 1
0
RTDB_API RTK_CURSOR PMC_API create_tag(
	RTK_CURSOR group,
	PCTAG_KEY tag, 
	PCSTATIC_TAG_DATA sd
	)
{
	RTK_CURSOR	handle;
	RTK_GROUP * grp;
	RTK_TAG 	t;

	handle = open_tag_g(group, tag);
	if(handle){
		return handle;
	}

	if(g_dwTags >= g_dwMaxTags){
		rtk_set_last_error(RTDB_HARD_CONSTRAINTS);
		return 0;
	}

	grp = (RTK_GROUP*)cursor_get_item(group);
	if(!grp){
		return 0;
	}
	ZeroMemory(&t, sizeof(t));
	t.key = *tag;
	make_unified_key(t.key);
	t.s = *sd;
	t.node = grp->node;
	t.group = grp->key;
	handle = (RTK_CURSOR)_HTAG::create((TAG_TABLE*)grp->itemtable, t.key, t);
	RTK_TAG * pTag = (RTK_TAG*)cursor_get_item(handle);
	if(pTag){
		ZeroMemory(&pTag->d, sizeof(pTag->d));
		set_value_type(pTag->d.Value.Flags, get_value_type(pTag->s.Flags));
		RtkInitializeListHead(&pTag->d.DeviceLink);
		RtkInitializeListHead(&pTag->d.RefreshLink);
		FIRE_EVENT(OnAddTag, (pTag));
		g_dwTags++;
	}

	return handle;
}
Ejemplo n.º 2
0
/*
	getBufferValues

	Environment :

	buffer lock acquired at least non-exclusively

	Algorithm description:

	on entry, we've got three time ranges

	a) time range for which this buffer has archive data
	b) time range that client demands archive data
	c) time range of the tag data array
	
	we denote them as Ta, Tb, Tc, respectively. 

	Ta and Tb must intersect, or else there is a bug(should 
	not go here).

	Tb and Tc might intersect, in which case there will
	be some archived data returned. Or they might not
	intersect, in which case there'll be no archived data
	returned.

	Either case, the number of tag data returned is determined
	by the intersection length of Tc and Tb and irrelavant of
	time range Ta. 

	Time range Ta only serves as a hint to find a tag's
	archive data by timestamp.
*/
__uint CArchiveBuffer::getBufferValues(
	PCTAG_NAME tag, 
	hislog_key_t startTime,
	__uint count,
	__uint step,
	hislog_item_t * buffer
	)
{
	__uint ret;
	archive_index_table_item_t * ti;
	archive_item_t * values;
	archive_item_t * item, * margin;
	hislog_key_t endTime;
	hislog_key_t Tc_1, Tc_2;
	__uint n;
	
	assert(isValid());

	endTime = startTime + (count - 1) * step;
	
	__try{
		ti = (archive_index_table_item_t*)bsearch(
			tag, 
			m_indices, 
			m_hdr->tagCount, 
			sizeof(archive_index_table_item_t), 
			_compareTagName
			);
		if(!ti){
			return 0;
		}
		if(ti->valueCount < 2){
			return 0;
		}
		values = (archive_item_t *)((__u8*)m_archive.GetPointer() + ti->dataOffset);
		//3 now we gonna get the timed value from this array
		//3 A quich and dirty implementation
		ret = 0;

		// align them to grid points
		Tc_1 = commModeCeil(startTime, values[0].time, step);
		Tc_2 = commModeFloor(startTime, values[ti->valueCount - 1].time, step);
		
		// compute the intersection of range [Tc_1, Tc_2] and [startTime, endTime]
		Tc_1 = Tc_1 > startTime? Tc_1 : startTime;
		Tc_2 = Tc_2 > endTime? endTime : Tc_2;
		
		if(Tc_1 > Tc_2){
			// no intersection
			return 0;
		}

		if(Tc_1 < m_startTime || Tc_2 > m_endTime){
			// this is an invalid archive, we don't proceed for fear
			// that unexpected result might occur
			rtk_set_last_error(HISLOG_INVALID_ARCHIVE);
			return 0;
		}

		assert(!((Tc_1 - startTime) % step));
		assert(!((Tc_2 - startTime) % step));
		
		// prolog
		if(Tc_1 > startTime){
			// make compensation
			n = (Tc_1 - startTime) / step;
			ret += n;
			startTime += n * step;
			buffer += n;
		}

		item = values;
		margin = &values[ti->valueCount - 1];
		
		// actual values in the archive
		do{
			item = _locateItem(item, margin, startTime);
			assert(item);
			assert(item->time <= startTime);
			// get value for startTime
			if(item->time == startTime || item == margin){
				*buffer = item->value;
			}else{			
				// interpolate
				interpolate(
					&item->value, 
					&item[1].value,
					buffer, 
					item->time,
					item[1].time,
					startTime
					);
			}
			buffer++;
			ret++;
			startTime += step;
		}while(startTime <= Tc_2 && ret < count);
	}__except(EXCEPTION_EXECUTE_HANDLER){
		rtk_set_last_error(HISLOG_INVALID_ARCHIVE);
		return 0;
	}

	return ret;
}