[ Non-logical Variables, Arrays, Bags, Shelves and Stores | Reference Manual | Alphabetic Index ]

# store_test_and_set(+StoreHandle, ++Key, ++OldValue, ?NewValue)

Update an existing entry in a store object

StoreHandle
  A store handle or store name
Key
  A ground term
OldValue
  An arbitrary term (should be ground)
NewValue
  An arbitrary term

## Description

Looks up a store entry under the given key. If one exists and its value is identical to OldValue, it is replaced with New Value. Otherwise the predicate fails. It could be defined as:

            store_test_and_set(Store, Key, OldValue, NewValue) :-
                with_mutex(Store, (
                        store_get(Store, Key, Entry),
                        OldValue == Entry,
                        store_set(Store, Key, NewValue)
                )).

Note that the old value is compared for identity, which implies that only ground terms can possibly be identical to the stored value (because the stored term has different variables).

The key can be arbitrarily complex, but must be a ground term. The value can be an arbitrary term, and may contain uninstantiated variables. Note that values are copied when being stored or retrieved, therefore a retrieved nonground value will contain fresh variables rather than the original ones (this is similar to the behaviour of bags, shelves and global variables).

The complexity of the update operation is linear in the size of the key and both values. NewValue is copied. For indexing purposes, a hash value is computed from the key, and the full depth of the key is taken into account.

Note: If StoreHandle is not a handle, then it must be an atom or a compound term, and the store is identified by this term's toplevel functor together with the context module.

### Modes and Determinism

- store_test_and_set(+, ++, ++, ?) is semidet

### Modules

This predicate is sensitive to its module context (tool predicate, see @/2).

### Fail Conditions

Fails is there is no previous entry, or it is not identical to OldValue

### Exceptions

(4) instantiation fault
  StoreHandle is uninstantiated
(4) instantiation fault
  Key is not ground
(5) type error
  StoreHandle is neither atom nor compound term nor store handle
(45) named object does not exist
  StoreHandle is not the name of a store

## Examples

        ?- store_create(Handle),
           store_test_and_set(Handle, tom, Old, first).	% no entry yet

        No (0.00s cpu)

        ?- store_create(Handle),
           store_set(Handle, tom, first),
           store_test_and_set(Handle, tom, first, second),
           store_get(Handle, tom, New).

        Handle = $&(store,"17h3")
        Old = first
        New = second
        Yes (0.00s cpu)

        ?- store_create(Handle),
           store_set(Handle, tom, first),
           store_test_and_set(Handle, tom, premier, second).

        No (0.00s cpu)

## See Also

store / 1, store_create / 1, store_contains / 2, store_count / 2, store_get / 3, store_inc / 2, store_insert / 3, store_set / 3, store_update / 4