Add CHAN_IGNORE_DUP to ignore duplicates
This commit is contained in:
		
							parent
							
								
									ab3e823134
								
							
						
					
					
						commit
						e625897766
					
				| @ -63,22 +63,6 @@ set_dirty(struct chan *chan) | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| check_duplicates(struct chan *chan, struct value *v) | ||||
| { | ||||
| 	/* If duplicates are allowed just skip the check */ | ||||
| 	if (chan->prop[CHAN_ALLOW_DUP]) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	if (value_is_equal(&chan->last_value, v)) { | ||||
| 		err("%s: same value as last_value %s", | ||||
| 				chan->name, value_str(chan->last_value)); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| chan_set(struct chan *chan, struct value value) | ||||
| { | ||||
| @ -92,9 +76,19 @@ chan_set(struct chan *chan, struct value value) | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	if (check_duplicates(chan, &value) != 0) { | ||||
| 		err("%s: cannot set duplicated value", chan->name); | ||||
| 		return -1; | ||||
| 	/* If duplicates are allowed just skip the check */ | ||||
| 	if (!chan->prop[CHAN_ALLOW_DUP]) { | ||||
| 		if (value_is_equal(&chan->last_value, &value)) { | ||||
| 			if (chan->prop[CHAN_IGNORE_DUP]) { | ||||
| 				dbg("%s: value already set to %s", | ||||
| 						chan->name, value_str(value)); | ||||
| 				return 0; | ||||
| 			} else { | ||||
| 				err("%s: same value as last_value %s", | ||||
| 						chan->name, value_str(chan->last_value)); | ||||
| 				return -1; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	dbg("%s: sets value to %s", chan->name, value_str(value)); | ||||
| @ -127,9 +121,19 @@ chan_push(struct chan *chan, struct value value) | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	if (check_duplicates(chan, &value) != 0) { | ||||
| 		err("%s: cannot push a duplicated value", chan->name); | ||||
| 		return -1; | ||||
| 	/* If duplicates are allowed just skip the check */ | ||||
| 	if (!chan->prop[CHAN_ALLOW_DUP]) { | ||||
| 		if (value_is_equal(&chan->last_value, &value)) { | ||||
| 			if (chan->prop[CHAN_IGNORE_DUP]) { | ||||
| 				dbg("%s: value already set to %s", | ||||
| 						chan->name, value_str(value)); | ||||
| 				return 0; | ||||
| 			} else { | ||||
| 				err("%s: same value as last_value %s", | ||||
| 						chan->name, value_str(chan->last_value)); | ||||
| 				return -1; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	struct chan_stack *stack = &chan->data.stack; | ||||
|  | ||||
| @ -19,6 +19,7 @@ enum chan_type { | ||||
| enum chan_prop { | ||||
| 	CHAN_DIRTY_WRITE = 0, | ||||
| 	CHAN_ALLOW_DUP, | ||||
| 	CHAN_IGNORE_DUP, | ||||
| 	CHAN_MAXPROP, | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -41,6 +41,8 @@ test_dirty(void) | ||||
| 
 | ||||
| 	if (chan_flush(&chan) != 0) | ||||
| 		die("chan_flush failed\n"); | ||||
| 
 | ||||
| 	err("OK"); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| @ -72,10 +74,14 @@ test_single(void) | ||||
| 
 | ||||
| 	if (!value_is_equal(&value, &one)) | ||||
| 		die("chan_read returned unexpected value\n"); | ||||
| 
 | ||||
| 	err("OK"); | ||||
| } | ||||
| 
 | ||||
| /* Test that writting the same value to a channel raises an error, but not if we
 | ||||
|  * set the CHAN_ALLOW_DUP flag */ | ||||
| static void | ||||
| test_duplicate(void) | ||||
| test_allow_dup(void) | ||||
| { | ||||
| 	struct chan chan; | ||||
| 	chan_init(&chan, CHAN_SINGLE, "testchan"); | ||||
| @ -90,12 +96,44 @@ test_duplicate(void) | ||||
| 	if (chan_set(&chan, value_int64(1)) == 0) | ||||
| 		die("chan_set didn't fail\n"); | ||||
| 
 | ||||
| 	/* Now enable duplicates */ | ||||
| 	/* Allow duplicates */ | ||||
| 	chan_prop_set(&chan, CHAN_ALLOW_DUP, 1); | ||||
| 
 | ||||
| 	/* Then it should allow writting the same value */ | ||||
| 	if (chan_set(&chan, value_int64(1)) != 0) | ||||
| 		die("chan_set failed\n"); | ||||
| 
 | ||||
| 	/* Also ensure the channel is dirty */ | ||||
| 	if (!chan.is_dirty) | ||||
| 		die("chan is not dirty"); | ||||
| 
 | ||||
| 	err("OK"); | ||||
| } | ||||
| 
 | ||||
| /* Test that writting the same value to a channel with the flag CHAN_IGNORE_DUP,
 | ||||
|  * causes the channel to remain clean (without the is_dirty flag set) */ | ||||
| static void | ||||
| test_ignore_dup(void) | ||||
| { | ||||
| 	struct chan chan; | ||||
| 	chan_init(&chan, CHAN_SINGLE, "testchan"); | ||||
| 	chan_prop_set(&chan, CHAN_IGNORE_DUP, 1); | ||||
| 
 | ||||
| 	if (chan_set(&chan, value_int64(1)) != 0) | ||||
| 		die("chan_set failed\n"); | ||||
| 
 | ||||
| 	if (chan_flush(&chan) != 0) | ||||
| 		die("chan_flush failed\n"); | ||||
| 
 | ||||
| 	/* Write the same value */ | ||||
| 	if (chan_set(&chan, value_int64(1)) != 0) | ||||
| 		die("chan_set failed"); | ||||
| 
 | ||||
| 	/* And ensure the channel is not dirty */ | ||||
| 	if (chan.is_dirty) | ||||
| 		die("chan is dirty"); | ||||
| 
 | ||||
| 	err("OK"); | ||||
| } | ||||
| 
 | ||||
| //static void
 | ||||
| @ -159,7 +197,8 @@ int main(void) | ||||
| { | ||||
| 	test_single(); | ||||
| 	test_dirty(); | ||||
| 	test_duplicate(); | ||||
| 	test_allow_dup(); | ||||
| 	test_ignore_dup(); | ||||
| 	//test_stack();
 | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user