From 1e00868d7808fbe8389138244f9f186a636279bc Mon Sep 17 00:00:00 2001 From: Brice Videau Date: Fri, 11 Oct 2024 16:47:58 -0500 Subject: [PATCH] Tree configurations are immutable and created valid. --- bindings/python/cconfigspace/tree.py | 9 --- .../python/cconfigspace/tree_configuration.py | 7 -- bindings/python/cconfigspace/tree_space.py | 16 ---- bindings/python/test/test_tree.py | 2 - bindings/python/test/test_tree_space.py | 26 +----- bindings/ruby/lib/cconfigspace/tree.rb | 10 --- .../lib/cconfigspace/tree_configuration.rb | 7 -- bindings/ruby/lib/cconfigspace/tree_space.rb | 17 ---- bindings/ruby/test/test_tree.rb | 2 - bindings/ruby/test/test_tree_space.rb | 26 +----- include/cconfigspace/tree.h | 36 ++------- include/cconfigspace/tree_configuration.h | 27 +------ include/cconfigspace/tree_space.h | 61 ++------------ src/tree.c | 21 ----- src/tree_configuration.c | 23 +++--- src/tree_space.c | 79 ++++++------------- src/tree_space_dynamic.c | 2 - src/tree_space_internal.h | 13 +++ src/tree_space_static.c | 11 ++- tests/test_dynamic_tree_space.c | 29 +++---- tests/test_static_tree_space.c | 10 --- tests/test_tree.c | 11 +-- 22 files changed, 97 insertions(+), 348 deletions(-) diff --git a/bindings/python/cconfigspace/tree.py b/bindings/python/cconfigspace/tree.py index 7581dfc4..01e454d6 100644 --- a/bindings/python/cconfigspace/tree.py +++ b/bindings/python/cconfigspace/tree.py @@ -11,7 +11,6 @@ ccs_tree_get_parent = _ccs_get_function("ccs_tree_get_parent", [ccs_tree, ct.POINTER(ccs_tree), ct.POINTER(ct.c_size_t)]) ccs_tree_get_position = _ccs_get_function("ccs_tree_get_position", [ccs_tree, ct.c_size_t, ct.POINTER(ct.c_size_t), ct.POINTER(ct.c_size_t)]) ccs_tree_get_values = _ccs_get_function("ccs_tree_get_values", [ccs_tree, ct.c_size_t, ct.POINTER(Datum), ct.POINTER(ct.c_size_t)]) -ccs_tree_position_is_valid = _ccs_get_function("ccs_tree_position_is_valid", [ccs_tree, ct.c_size_t, ct.POINTER(ct.c_size_t), ct.POINTER(ccs_bool)]) ccs_tree_get_values_at_position = _ccs_get_function("ccs_tree_get_values_at_position", [ccs_tree, ct.c_size_t, ct.POINTER(ct.c_size_t), ct.c_size_t, ct.POINTER(Datum)]) ccs_tree_get_node_at_position = _ccs_get_function("ccs_tree_get_node_at_position", [ccs_tree, ct.c_size_t, ct.POINTER(ct.c_size_t), ct.POINTER(ccs_tree)]) ccs_tree_get_weight = _ccs_get_function("ccs_tree_get_weight", [ccs_tree, ct.POINTER(ccs_float)]) @@ -142,14 +141,6 @@ def values(self): Error.check(res) return [x.value for x in v] - def position_is_valid(self, position): - count = len(position) - v = (ct.c_size_t * count)(*position) - b = ccs_bool() - res = ccs_tree_position_is_valid(self.handle, count, v, ct.byref(b)) - Error.check(res) - return not (b.value == 0) - def get_values_at_position(self, position): count = len(position) v1 = (ct.c_size_t * count)(*position) diff --git a/bindings/python/cconfigspace/tree_configuration.py b/bindings/python/cconfigspace/tree_configuration.py index 62a18936..619e93c5 100644 --- a/bindings/python/cconfigspace/tree_configuration.py +++ b/bindings/python/cconfigspace/tree_configuration.py @@ -11,7 +11,6 @@ ccs_tree_configuration_get_position = _ccs_get_function("ccs_tree_configuration_get_position", [ccs_tree_configuration, ct.c_size_t, ct.POINTER(ct.c_size_t), ct.POINTER(ct.c_size_t)]) ccs_tree_configuration_get_values = _ccs_get_function("ccs_tree_configuration_get_values", [ccs_tree_configuration, ct.c_size_t, ct.POINTER(Datum), ct.POINTER(ct.c_size_t)]) ccs_tree_configuration_get_node = _ccs_get_function("ccs_tree_configuration_get_node", [ccs_tree_configuration, ct.POINTER(ccs_tree)]) -ccs_tree_configuration_check = _ccs_get_function("ccs_tree_configuration_check", [ccs_tree_configuration, ct.POINTER(ccs_bool)]) ccs_tree_configuration_hash = _ccs_get_function("ccs_tree_configuration_hash", [ccs_tree_configuration, ct.POINTER(ccs_hash)]) ccs_tree_configuration_cmp = _ccs_get_function("ccs_tree_configuration_cmp", [ccs_tree_configuration, ccs_tree_configuration, ct.POINTER(ct.c_int)]) @@ -101,12 +100,6 @@ def node(self): self._node = Tree.from_handle(v) return self._node - def check(self): - valid = ccs_bool() - res = ccs_tree_configuration_check(self.handle, ct.byref(valid)) - Error.check(res) - return not (valid.value == 0) - @property def hash(self): if hasattr(self, "_hash"): diff --git a/bindings/python/cconfigspace/tree_space.py b/bindings/python/cconfigspace/tree_space.py index 9e993bcc..f1ded72d 100644 --- a/bindings/python/cconfigspace/tree_space.py +++ b/bindings/python/cconfigspace/tree_space.py @@ -17,8 +17,6 @@ class TreeSpaceType(CEnumeration): ccs_tree_space_get_tree = _ccs_get_function("ccs_tree_space_get_tree", [ccs_tree_space, ct.POINTER(ccs_tree)]) ccs_tree_space_get_node_at_position = _ccs_get_function("ccs_tree_space_get_node_at_position", [ccs_tree_space, ct.c_size_t, ct.POINTER(ct.c_size_t), ct.POINTER(ccs_tree)]) ccs_tree_space_get_values_at_position = _ccs_get_function("ccs_tree_space_get_values_at_position", [ccs_tree_space, ct.c_size_t, ct.POINTER(ct.c_size_t), ct.c_size_t, ct.POINTER(Datum)]) -ccs_tree_space_check_position = _ccs_get_function("ccs_tree_space_check_position", [ccs_tree_space, ct.c_size_t, ct.POINTER(ct.c_size_t), ct.POINTER(ccs_bool)]) -ccs_tree_space_check_configuration = _ccs_get_function("ccs_tree_space_check_configuration", [ccs_tree_space, ccs_tree_configuration, ct.POINTER(ccs_bool)]) ccs_tree_space_sample = _ccs_get_function("ccs_tree_space_sample", [ccs_tree_space, ccs_features, ccs_rng, ct.POINTER(ccs_tree_configuration)]) ccs_tree_space_samples = _ccs_get_function("ccs_tree_space_samples", [ccs_tree_space, ccs_features, ccs_rng, ct.c_size_t, ct.POINTER(ccs_tree_configuration)]) @@ -106,20 +104,6 @@ def get_values_at_position(self, position): Error.check(res) return [x.value for x in v2] - def check_position(self, position): - count = len(position) - v = (ct.c_size_t * count)(*position) - b = ccs_bool() - res = ccs_tree_space_check_position(self.handle, count, v, ct.byref(b)) - Error.check(res) - return not (b.value == 0) - - def check_configuration(self, configuration): - b = ccs_bool() - res = ccs_tree_space_check_configuration(self.handle, configuration.handle, ct.byref(b)) - Error.check(res) - return not (b.value == 0) - def sample(self, features = None, rng = None): if features is not None: features = features.handle diff --git a/bindings/python/test/test_tree.py b/bindings/python/test/test_tree.py index d5fb5641..4f4422ff 100644 --- a/bindings/python/test/test_tree.py +++ b/bindings/python/test/test_tree.py @@ -32,7 +32,6 @@ def test_create(self): for i in root.samples(rng, 100): self.assertTrue( i is None or (i >= 0 and i < 4) ) - self.assertFalse( root.position_is_valid([2, 1]) ) child = ccs.Tree(arity = 3, value = "bar" ) self.assertEqual( "bar", child.value ) root.set_child(2, child) @@ -42,7 +41,6 @@ def test_create(self): self.assertEqual( 1, child.depth ) self.assertEqual( child.handle.value, root.get_child(2).handle.value ) self.assertEqual( child.handle.value, root.get_node_at_position([2]).handle.value ) - self.assertTrue( root.position_is_valid([2, 1]) ) self.assertEqual( ["foo", "bar"], root.get_values_at_position([2]) ) buff = root.serialize() diff --git a/bindings/python/test/test_tree_space.py b/bindings/python/test/test_tree_space.py index d6862dbb..1ebc704c 100644 --- a/bindings/python/test/test_tree_space.py +++ b/bindings/python/test/test_tree_space.py @@ -29,14 +29,9 @@ def test_static_tree_space(self): self.assertEqual( tree.handle.value, ts.get_node_at_position([]).handle.value ) self.assertEqual( 201, ts.get_node_at_position([1, 1]).value ) self.assertEqual( [400, 301, 201], ts.get_values_at_position([1, 1]) ) - self.assertTrue( ts.check_position([1, 1]) ) - self.assertFalse( ts.check_position([1, 4]) ) - tc = ts.sample() - self.assertTrue( ts.check_configuration(tc) ) - - for x in ts.samples(100): - self.assertTrue( ts.check_configuration(x) ) + ts.sample() + ts.samples(100) buff = ts.serialize() ts2 = ccs.Object.deserialize(buffer = buff) @@ -68,14 +63,8 @@ def get_vector_data(otype, name): self.assertEqual( tree.handle.value, ts.get_node_at_position([]).handle.value ) self.assertEqual( 201, ts.get_node_at_position([1, 1]).value ) self.assertEqual( [400, 301, 201], ts.get_values_at_position([1, 1]) ) - self.assertTrue( ts.check_position([1, 1]) ) - self.assertFalse( ts.check_position([1, 4]) ) - tc = ts.sample() - self.assertTrue( ts.check_configuration(tc) ) - - for i in range(100): - tc = ts.sample() - self.assertTrue( ts.check_configuration(tc) ) + ts.sample() + ts.samples(100) buff = ts.serialize() ts2 = ccs.deserialize(buffer = buff, vector_callback = get_vector_data) @@ -84,11 +73,6 @@ def get_vector_data(otype, name): def test_tree_configuration(self): tree = generate_tree(4, 0) ts = ccs.StaticTreeSpace(name = 'space', tree = tree) - tc = ts.sample() - self.assertTrue( tc.check() ) - for x in ts.samples(100): - self.assertTrue( x.check() ) - tc = ccs.TreeConfiguration(tree_space = ts, position = [1, 1]) self.assertEqual( tc.tree_space.handle.value, ts.handle.value ) self.assertEqual( 2, tc.position_size ) @@ -96,7 +80,5 @@ def test_tree_configuration(self): self.assertEqual( [400, 301, 201], tc.values ) self.assertEqual( ts.get_node_at_position([1, 1]).handle.value, tc.node.handle.value ) tc2 = ccs.TreeConfiguration(tree_space = ts, position = [1, 0]) - self.assertTrue( tc.check() ) - self.assertTrue( tc2.check() ) self.assertNotEqual( tc.hash, tc2.hash ) self.assertTrue( tc < tc2 or tc > tc2 ) diff --git a/bindings/ruby/lib/cconfigspace/tree.rb b/bindings/ruby/lib/cconfigspace/tree.rb index 749ff19a..96117fb5 100644 --- a/bindings/ruby/lib/cconfigspace/tree.rb +++ b/bindings/ruby/lib/cconfigspace/tree.rb @@ -9,7 +9,6 @@ module CCS attach_function :ccs_tree_get_parent, [:ccs_tree_t, :pointer, :pointer], :ccs_result_t attach_function :ccs_tree_get_position, [:ccs_tree_t, :size_t, :pointer, :pointer], :ccs_result_t attach_function :ccs_tree_get_values, [:ccs_tree_t, :size_t, :pointer, :pointer], :ccs_result_t - attach_function :ccs_tree_position_is_valid, [:ccs_tree_t, :size_t, :pointer, :pointer], :ccs_result_t attach_function :ccs_tree_get_values_at_position, [:ccs_tree_t, :size_t, :pointer, :size_t, :pointer], :ccs_result_t attach_function :ccs_tree_get_node_at_position, [:ccs_tree_t, :size_t, :pointer, :pointer], :ccs_result_t attach_function :ccs_tree_get_weight, [:ccs_tree_t, :pointer], :ccs_result_t @@ -82,15 +81,6 @@ def index alias depth num_position_items alias position position_items - def position_is_valid?(position) - count = position.size - ptr1 = MemoryPointer::new(:size_t, count) - ptr1.write_array_of_size_t(position) - ptr2 = MemoryPointer::new(:ccs_bool_t) - CCS.error_check CCS.ccs_tree_position_is_valid(@handle, count, ptr1, ptr2) - ptr2.read_ccs_bool_t == CCS::FALSE ? false : true - end - def get_values_at_position(position) count1 = position.size ptr1 = MemoryPointer::new(:size_t, count1) diff --git a/bindings/ruby/lib/cconfigspace/tree_configuration.rb b/bindings/ruby/lib/cconfigspace/tree_configuration.rb index 021a3b42..33772a5f 100644 --- a/bindings/ruby/lib/cconfigspace/tree_configuration.rb +++ b/bindings/ruby/lib/cconfigspace/tree_configuration.rb @@ -6,7 +6,6 @@ module CCS attach_function :ccs_tree_configuration_get_position, [:ccs_tree_configuration_t, :size_t, :pointer, :pointer], :ccs_result_t attach_function :ccs_tree_configuration_get_values, [:ccs_tree_configuration_t, :size_t, :pointer, :pointer], :ccs_result_t attach_function :ccs_tree_configuration_get_node, [:ccs_tree_configuration_t, :pointer], :ccs_result_t - attach_function :ccs_tree_configuration_check, [:ccs_tree_configuration_t, :pointer], :ccs_result_t attach_function :ccs_tree_configuration_hash, [:ccs_tree_configuration_t, :pointer], :ccs_result_t attach_function :ccs_tree_configuration_cmp, [:ccs_tree_configuration_t, :ccs_tree_configuration_t, :pointer], :ccs_result_t @@ -40,12 +39,6 @@ def self.from_handle(handle, retain: true, auto_release: true) alias position_size num_position_items alias position position_items - def check - ptr = MemoryPointer::new(:ccs_bool_t) - CCS.error_check CCS.ccs_tree_configuration_check(@handle, ptr) - ptr.read_ccs_bool_t == CCS::FALSE ? false : true - end - def <=>(other) ptr = MemoryPointer::new(:int) CCS.error_check CCS.ccs_tree_configuration_cmp(@handle, other, ptr) diff --git a/bindings/ruby/lib/cconfigspace/tree_space.rb b/bindings/ruby/lib/cconfigspace/tree_space.rb index 786618ca..68dc12bb 100644 --- a/bindings/ruby/lib/cconfigspace/tree_space.rb +++ b/bindings/ruby/lib/cconfigspace/tree_space.rb @@ -17,8 +17,6 @@ def read_ccs_tree_space_type_t attach_function :ccs_tree_space_get_tree, [:ccs_tree_space_t, :pointer], :ccs_result_t attach_function :ccs_tree_space_get_node_at_position, [:ccs_tree_space_t, :size_t, :pointer, :pointer], :ccs_result_t attach_function :ccs_tree_space_get_values_at_position, [:ccs_tree_space_t, :size_t, :pointer, :size_t, :pointer], :ccs_result_t - attach_function :ccs_tree_space_check_position, [:ccs_tree_space_t, :size_t, :pointer, :pointer], :ccs_result_t - attach_function :ccs_tree_space_check_configuration, [:ccs_tree_space_t, :ccs_tree_configuration_t, :pointer], :ccs_result_t attach_function :ccs_tree_space_sample, [:ccs_tree_space_t, :ccs_features_t, :ccs_rng_t, :pointer], :ccs_result_t attach_function :ccs_tree_space_samples, [:ccs_tree_space_t, :ccs_features_t, :ccs_rng_t, :size_t, :pointer], :ccs_result_t @@ -68,21 +66,6 @@ def get_values_at_position(position) count2.times.collect { |i| Datum::new(ptr2[i]).value } end - def check_position(position) - count = position.size - ptr1 = MemoryPointer::new(:size_t, count) - ptr1.write_array_of_size_t(position) - ptr2 = MemoryPointer::new(:ccs_bool_t) - CCS.error_check CCS.ccs_tree_space_check_position(@handle, count, ptr1, ptr2) - ptr2.read_ccs_bool_t == CCS::FALSE ? false : true - end - - def check_configuration(configuration) - ptr = MemoryPointer::new(:ccs_bool_t) - CCS.error_check CCS.ccs_tree_space_check_configuration(@handle, configuration, ptr) - ptr.read_ccs_bool_t == CCS::FALSE ? false : true - end - def sample(features: nil, rng: nil) ptr = MemoryPointer::new(:ccs_tree_configuration_t) CCS.error_check CCS.ccs_tree_space_sample(@handle, features, rng, ptr) diff --git a/bindings/ruby/test/test_tree.rb b/bindings/ruby/test/test_tree.rb index da451f8f..ba5ff1d3 100644 --- a/bindings/ruby/test/test_tree.rb +++ b/bindings/ruby/test/test_tree.rb @@ -29,7 +29,6 @@ def test_create assert( i.nil? || (i >= 0 and i < 4) ) } - refute( root.position_is_valid?([2, 1]) ) child = CCS::Tree.new(arity: 3, value: "bar" ) assert_equal( "bar", child.value ) root.set_child(2, child) @@ -39,7 +38,6 @@ def test_create assert_equal( 1, child.depth ) assert_equal( child.handle, root.get_child(2).handle ) assert_equal( child.handle, root.get_node_at_position([2]).handle ) - assert( root.position_is_valid?([2, 1]) ) assert_equal( ["foo", "bar"], root.get_values_at_position([2]) ) buff = root.serialize diff --git a/bindings/ruby/test/test_tree_space.rb b/bindings/ruby/test/test_tree_space.rb index 7fcb4a74..2103cb6e 100644 --- a/bindings/ruby/test/test_tree_space.rb +++ b/bindings/ruby/test/test_tree_space.rb @@ -26,15 +26,9 @@ def test_static_tree_space assert_equal( tree.handle, ts.get_node_at_position([]).handle ) assert_equal( 201, ts.get_node_at_position([1, 1]).value ) assert_equal( [400, 301, 201], ts.get_values_at_position([1, 1]) ) - assert( ts.check_position([1, 1]) ) - refute( ts.check_position([1, 4]) ) - tc = ts.sample - assert( ts.check_configuration(tc) ) - - ts.samples(100).each{ |x| - assert( ts.check_configuration(x) ) - } + ts.sample + ts.samples(100) buff = ts.serialize ts2 = CCS.deserialize(buffer: buff) @@ -64,15 +58,9 @@ def test_dynamic_tree_space assert_equal( tree.handle, ts.get_node_at_position([]).handle ) assert_equal( 201, ts.get_node_at_position([1, 1]).value ) assert_equal( [400, 301, 201], ts.get_values_at_position([1, 1]) ) - assert( ts.check_position([1, 1]) ) - refute( ts.check_position([1, 4]) ) - tc = ts.sample - assert( ts.check_configuration(tc) ) - 100.times { - tc = ts.sample - assert( ts.check_configuration(tc) ) - } + ts.sample + ts.samples(100) buff = ts.serialize ts2 = CCS::deserialize(buffer: buff, vector_callback: get_vector_data) @@ -82,10 +70,6 @@ def test_dynamic_tree_space def test_tree_configuration tree = generate_tree(4, 0) ts = CCS::StaticTreeSpace.new(name: 'space', tree: tree) - tc = ts.sample - assert( tc.check ) - ts.samples(100).each { |x| assert( x.check ) } - tc = CCS::TreeConfiguration.new(tree_space: ts, position: [1, 1]) assert_equal( tc.tree_space.handle, ts.handle ) assert_equal( 2, tc.position_size ) @@ -93,8 +77,6 @@ def test_tree_configuration assert_equal( [400, 301, 201], tc.values ) assert_equal( ts.get_node_at_position([1, 1]).handle, tc.node.handle ) tc2 = CCS::TreeConfiguration.new(tree_space: ts, position: [1, 0]) - assert( tc.check() ) - assert( tc2.check() ) refute_equal( tc.hash, tc2.hash ) assert( tc < tc2 || tc > tc2 ) end diff --git a/include/cconfigspace/tree.h b/include/cconfigspace/tree.h index f9a34ef0..7eca8bb1 100644 --- a/include/cconfigspace/tree.h +++ b/include/cconfigspace/tree.h @@ -191,29 +191,6 @@ ccs_tree_get_values( ccs_datum_t *values, size_t *num_values_ret); -/** - * Check if a position can be reached from a tree node. - * @param[in] tree - * @param[in] position_size the number of entries in the \p position array - * @param[in] position an array of indexes defining a location in the tree. - * @param[out] is_valid_ret a pointer to a variable that will hold the result - * of the check. Result will be CCS_TRUE if the - * configuration is valid. Result will be CCS_FALSE if - * the position does not reference a node of the tree. - * @return #CCS_RESULT_SUCCESS on success - * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p tree is not a valid CCS tree - * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p is_valid_ret is NULL; or if \p - * position is NULL and \p position_size is greater than 0 - * @remarks - * This function is thread-safe - */ -extern ccs_result_t -ccs_tree_position_is_valid( - ccs_tree_t tree, - size_t position_size, - const size_t *position, - ccs_bool_t *is_valid_ret); - /** * Get the values along the path to a given position from a tree node. * @param[in] tree @@ -226,8 +203,10 @@ ccs_tree_position_is_valid( * are set to #CCS_DATA_TYPE_NONE * @return #CCS_RESULT_SUCCESS on success * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p tree is not a valid CCS tree - * @return #CCS_RESULT_ERROR_INVALID_TREE if the position does not reference - * node in the tree. + * @return #CCS_RESULT_ERROR_OUT_OF_BOUNDS if \p position does not define a + * valid position in \p tree + * @return #CCS_RESULT_ERROR_INVALID_TREE if one child node described by \p + * position is undefined in \p tree * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p values is NULL; if \p * num_values is less than \p position_size + 1; or if \p position is NULL and * \p position_size is greater than 0 @@ -253,9 +232,10 @@ ccs_tree_get_values_at_position( * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p tree is not a valid CCS tree * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p tree_ret is NULL; or if \p * position is NULL and \p position_size is greater than 0 - * @return #CCS_RESULT_ERROR_INVALID_TREE if the position does not define a - * valid position in the tree space, or if this position is undefined in a - * static tree space. + * @return #CCS_RESULT_ERROR_OUT_OF_BOUNDS if \p position does not define a + * valid position in \p tree + * @return #CCS_RESULT_ERROR_INVALID_TREE if one child node described by \p + * position is undefined in \p tree * @remarks * This function is thread-safe */ diff --git a/include/cconfigspace/tree_configuration.h b/include/cconfigspace/tree_configuration.h index df3e516a..28e37dfc 100644 --- a/include/cconfigspace/tree_configuration.h +++ b/include/cconfigspace/tree_configuration.h @@ -29,7 +29,8 @@ extern "C" { * @return #CCS_RESULT_ERROR_INVALID_FEATURES if features feature space is not * the same as the feature space provided at \p tree_space creation. * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p configuration_ret is NULL; or - * if \p position is NULL and \p position_size is greater than 0 + * if \p position is NULL and \p position_size is greater than 0; or if \p + * position does not describe a valid position in the tree space * @return #CCS_RESULT_ERROR_OUT_OF_MEMORY if there was a lack of memory to * allocate the new tree configuration * @remarks @@ -118,8 +119,6 @@ ccs_tree_configuration_get_position( * @return #CCS_RESULT_SUCCESS on success * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p configuration is not a valid * CCS tree configuration - * @return #CCS_RESULT_ERROR_INVALID_TREE if the configuration's position does - * not reference a node in the tree. * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p values is NULL and \p * num_values is greater than 0; or if \p values is NULL and \p num_values_ret * is NULL; or if \p num_values is less than the number of values that would be @@ -142,8 +141,6 @@ ccs_tree_configuration_get_values( * @return #CCS_RESULT_SUCCESS on success * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p configuration is not a valid * CCS tree configuration - * @return #CCS_RESULT_ERROR_INVALID_TREE if the configuration's position does - * not reference a node in the tree. * @return #CCS_RESULT_ERROR_INVALID_VALUE \p node_ret is NULL * @remarks * This function is thread-safe @@ -153,26 +150,6 @@ ccs_tree_configuration_get_node( ccs_tree_configuration_t configuration, ccs_tree_t *node_ret); -/** - * Verify that the position of the configuration is a valid position in the - * tree space. - * @param[in] configuration - * @param[out] is_valid_ret a pointer to a variable that will hold the result - * of the check. Result will be #CCS_TRUE if the - * configuration is valid. Result will be #CCS_FALSE - * if the position does not reference a node of the - * tree. - * @return #CCS_RESULT_SUCCESS on success - * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p configuration is not a valid - * CCS tree configuration - * @remarks - * This function is thread-safe - */ -extern ccs_result_t -ccs_tree_configuration_check( - ccs_tree_configuration_t configuration, - ccs_bool_t *is_valid_ret); - /** * Compute a hash value for the configuration by hashing together the * tree space reference, the position size and the position values. diff --git a/include/cconfigspace/tree_space.h b/include/cconfigspace/tree_space.h index 58510d7b..c4f39683 100644 --- a/include/cconfigspace/tree_space.h +++ b/include/cconfigspace/tree_space.h @@ -245,9 +245,10 @@ ccs_tree_space_get_tree(ccs_tree_space_t tree_space, ccs_tree_t *tree_ret); * tree space * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p tree_ret is NULL; or if \p * position is NULL and \p position_size is greater than 0 - * @return #CCS_RESULT_ERROR_INVALID_TREE if the position does not define a - * valid position in the tree space, or if this position is undefined in a - * static tree space. + * @return #CCS_RESULT_ERROR_OUT_OF_BOUNDS if \p position does not define a + * valid position in \p tree_space + * @return #CCS_RESULT_ERROR_INVALID_TREE if one child node described by \p + * position is undefined and \p tree_space is a static tree space * @remarks * This function is NOT thread-safe for dynamic tree spaces as it can * instanciate new children @@ -272,8 +273,10 @@ ccs_tree_space_get_node_at_position( * @return #CCS_RESULT_SUCCESS on success * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p tree_space is not a valid CCS * tree space - * @return #CCS_RESULT_ERROR_INVALID_TREE if the position does not reference a - * node in the tree. + * @return #CCS_RESULT_ERROR_OUT_OF_BOUNDS if \p position does not define a + * valid position in \p tree_space + * @return #CCS_RESULT_ERROR_INVALID_TREE if one child node described by \p + * position is undefined and \p tree_space is a static tree space * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p values is NULL; if \p * num_values is less than \p position_size + 1; or if \p position is NULL and * \p position_size is greater than 0 @@ -289,54 +292,6 @@ ccs_tree_space_get_values_at_position( size_t num_values, ccs_datum_t *values); -/** - * Check the validity of a given position in a tree space. - * @param[in] tree_space - * @param[in] position_size the number of entries in the \p position array - * @param[in] position an array of indexes defining a location in the tree - * space. can be NULL if \p position_size is 0 - * @param[out] is_valid_ret a pointer to the variable that will contain the - * result - * @return #CCS_RESULT_SUCCESS on success - * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p tree_space is not a valid CCS - * tree space - * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p tree_ret is NULL; or if \p - * position is NULL and \p position_size is greater than 0 - * @return #CCS_RESULT_ERROR_INVALID_TREE if the position does not define a - * valid position in the tree space, or if this position is undefined in a - * static tree space. - * @remarks - * This function is NOT thread-safe for dynamic tree spaces as it can - * instanciate new children - */ -extern ccs_result_t -ccs_tree_space_check_position( - ccs_tree_space_t tree_space, - size_t position_size, - const size_t *position, - ccs_bool_t *is_valid_ret); - -/** - * Check the validity of a given configuration in a tree space. - * @param[in] tree_space - * @param[in] configuration - * @param[out] is_valid_ret a pointer to the variable that will contain the - * result - * @return #CCS_RESULT_SUCCESS on success - * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p tree_space is not a valid CCS - * tree space; or if \p configuration is not a valid CCS tree configuration - * @return #CCS_RESULT_ERROR_INVALID_CONFIGURATION if \p configuration is not - * associated to \p tree_space - * @remarks - * This function is NOT thread-safe for dynamic tree spaces as it can - * instanciate new children - */ -extern ccs_result_t -ccs_tree_space_check_configuration( - ccs_tree_space_t tree_space, - ccs_tree_configuration_t configuration, - ccs_bool_t *is_valid_ret); - /** * Get a tree configuration sampled randomly from a tree space. The space is * sampled according to the weight and bias of the individual tree nodes. If diff --git a/src/tree.c b/src/tree.c index 3c91993b..a775d9e4 100644 --- a/src/tree.c +++ b/src/tree.c @@ -450,27 +450,6 @@ ccs_tree_get_values( return CCS_RESULT_SUCCESS; } -ccs_result_t -ccs_tree_position_is_valid( - ccs_tree_t tree, - size_t position_size, - const size_t *position, - ccs_bool_t *is_valid_ret) -{ - CCS_CHECK_OBJ(tree, CCS_OBJECT_TYPE_TREE); - CCS_CHECK_ARY(position_size, position); - CCS_CHECK_PTR(is_valid_ret); - for (size_t i = 0; i < position_size; i++) { - if (!tree || position[i] >= tree->data->arity) { - *is_valid_ret = CCS_FALSE; - return CCS_RESULT_SUCCESS; - } - tree = tree->data->children[position[i]]; - } - *is_valid_ret = CCS_TRUE; - return CCS_RESULT_SUCCESS; -} - ccs_result_t ccs_tree_get_values_at_position( ccs_tree_t tree, diff --git a/src/tree_configuration.c b/src/tree_configuration.c index 7e8b001d..e6f70c92 100644 --- a/src/tree_configuration.c +++ b/src/tree_configuration.c @@ -159,6 +159,7 @@ ccs_create_tree_configuration( CCS_CHECK_PTR(configuration_ret); CCS_CHECK_ARY(position_size, position); ccs_result_t err; + ccs_bool_t is_valid; uintptr_t mem = (uintptr_t)calloc( 1, sizeof(struct _ccs_tree_configuration_s) + sizeof(struct _ccs_tree_configuration_data_s) + @@ -190,6 +191,14 @@ ccs_create_tree_configuration( config->data->features = features; memcpy(config->data->position, position, position_size * sizeof(size_t)); + CCS_VALIDATE_ERR_GOTO( + err, + _ccs_tree_space_check_position( + tree_space, config->data->position_size, + config->data->position, &is_valid), + errinit); + CCS_REFUTE_ERR_GOTO( + err, !is_valid, CCS_RESULT_ERROR_INVALID_VALUE, errinit); *configuration_ret = config; return CCS_RESULT_SUCCESS; errinit: @@ -278,20 +287,6 @@ ccs_tree_configuration_get_node( return CCS_RESULT_SUCCESS; } -ccs_result_t -ccs_tree_configuration_check( - ccs_tree_configuration_t configuration, - ccs_bool_t *is_valid_ret) -{ - CCS_CHECK_OBJ(configuration, CCS_OBJECT_TYPE_TREE_CONFIGURATION); - CCS_CHECK_PTR(is_valid_ret); - CCS_VALIDATE(ccs_tree_space_check_position( - configuration->data->tree_space, - configuration->data->position_size, - configuration->data->position, is_valid_ret)); - return CCS_RESULT_SUCCESS; -} - #define CCS_CMP(a, b) ((a) < (b) ? -1 : ((a) > (b) ? 1 : 0)) static ccs_result_t diff --git a/src/tree_space.c b/src/tree_space.c index 3be5750d..d696d713 100644 --- a/src/tree_space.c +++ b/src/tree_space.c @@ -97,41 +97,6 @@ ccs_tree_space_get_values_at_position( return CCS_RESULT_SUCCESS; } -ccs_result_t -ccs_tree_space_check_position( - ccs_tree_space_t tree_space, - size_t position_size, - const size_t *position, - ccs_bool_t *is_valid_ret) -{ - CCS_CHECK_OBJ(tree_space, CCS_OBJECT_TYPE_TREE_SPACE); - CCS_CHECK_ARY(position_size, position); - CCS_CHECK_PTR(is_valid_ret); - _ccs_tree_space_ops_t *ops = _ccs_tree_space_get_ops(tree_space); - CCS_VALIDATE(ops->check_position( - tree_space, position_size, position, is_valid_ret)); - return CCS_RESULT_SUCCESS; -} - -ccs_result_t -ccs_tree_space_check_configuration( - ccs_tree_space_t tree_space, - ccs_tree_configuration_t configuration, - ccs_bool_t *is_valid_ret) -{ - CCS_CHECK_OBJ(tree_space, CCS_OBJECT_TYPE_TREE_SPACE); - CCS_CHECK_OBJ(configuration, CCS_OBJECT_TYPE_TREE_CONFIGURATION); - CCS_REFUTE( - configuration->data->tree_space != tree_space, - CCS_RESULT_ERROR_INVALID_CONFIGURATION); - CCS_CHECK_PTR(is_valid_ret); - _ccs_tree_space_ops_t *ops = _ccs_tree_space_get_ops(tree_space); - CCS_VALIDATE(ops->check_position( - tree_space, configuration->data->position_size, - configuration->data->position, is_valid_ret)); - return CCS_RESULT_SUCCESS; -} - #undef utarray_oom #define utarray_oom() \ { \ @@ -152,41 +117,49 @@ _ccs_tree_space_samples( (_ccs_tree_space_common_data_t *)(tree_space->data); if (!rng) rng = data->rng; - ccs_result_t err = CCS_RESULT_SUCCESS; - UT_array *arr = NULL; + ccs_result_t err = CCS_RESULT_SUCCESS; + UT_array *arr = NULL; + UT_array *arr_total = NULL; utarray_new(arr, &_size_t_icd); + utarray_new(arr_total, &_size_t_icd); for (size_t i = 0; i < num_configurations; i++) { - size_t index; + size_t index, len; ccs_tree_t tree = data->tree; - if (tree) { + CCS_VALIDATE_ERR_GOTO( + err, _ccs_tree_samples(tree->data, rng, 1, &index), + err_arr); + while (index != tree->data->arity) { + utarray_push_back(arr, &index); + tree = tree->data->children[index]; + if (!tree) + break; CCS_VALIDATE_ERR_GOTO( err, _ccs_tree_samples(tree->data, rng, 1, &index), err_arr); - while (index != tree->data->arity) { - utarray_push_back(arr, &index); - tree = tree->data->children[index]; - if (!tree) - break; - CCS_VALIDATE_ERR_GOTO( - err, - _ccs_tree_samples( - tree->data, rng, 1, &index), - err_arr); - } } + len = utarray_len(arr); + utarray_push_back(arr_total, &len); + utarray_concat(arr_total, arr); + utarray_clear(arr); + } + for (size_t i = 0, offset = 0; i < num_configurations; i++) { + size_t len = *(size_t *)utarray_eltptr(arr_total, offset); + offset += 1; CCS_VALIDATE_ERR_GOTO( err, ccs_create_tree_configuration( - tree_space, features, utarray_len(arr), - (size_t *)utarray_eltptr(arr, 0), + tree_space, features, len, + (size_t *)utarray_eltptr(arr_total, offset), configurations + i), err_arr); - utarray_clear(arr); + offset += len; } err_arr: if (arr) utarray_free(arr); + if (arr_total) + utarray_free(arr_total); return err; } diff --git a/src/tree_space_dynamic.c b/src/tree_space_dynamic.c index c234dabf..0f3f0433 100644 --- a/src/tree_space_dynamic.c +++ b/src/tree_space_dynamic.c @@ -216,8 +216,6 @@ _ccs_tree_space_dynamic_check_position( const size_t *position, ccs_bool_t *is_valid_ret) { - CCS_CHECK_ARY(position_size, position); - CCS_CHECK_PTR(is_valid_ret); _ccs_tree_space_dynamic_data_t *data = (_ccs_tree_space_dynamic_data_t *)tree_space->data; ccs_tree_t parent = data->common_data.tree; diff --git a/src/tree_space_internal.h b/src/tree_space_internal.h index fac6dc1a..deb1e316 100644 --- a/src/tree_space_internal.h +++ b/src/tree_space_internal.h @@ -100,4 +100,17 @@ _ccs_serialize_bin_ccs_tree_space_common_data( return CCS_RESULT_SUCCESS; } +static inline ccs_result_t +_ccs_tree_space_check_position( + ccs_tree_space_t tree_space, + size_t position_size, + const size_t *position, + ccs_bool_t *is_valid_ret) +{ + _ccs_tree_space_ops_t *ops = + (_ccs_tree_space_ops_t *)tree_space->obj.ops; + CCS_VALIDATE(ops->check_position( + tree_space, position_size, position, is_valid_ret)); + return CCS_RESULT_SUCCESS; +} #endif //_TREE_SPACE_INTERNAL_H diff --git a/src/tree_space_static.c b/src/tree_space_static.c index 09112075..8683ad71 100644 --- a/src/tree_space_static.c +++ b/src/tree_space_static.c @@ -152,8 +152,15 @@ _ccs_tree_space_static_check_position( { _ccs_tree_space_static_data_t *data = (_ccs_tree_space_static_data_t *)tree_space->data; - CCS_VALIDATE(ccs_tree_position_is_valid( - data->common_data.tree, position_size, position, is_valid_ret)); + ccs_tree_t tree = data->common_data.tree; + for (size_t i = 0; i < position_size; i++) { + if (!tree || position[i] >= tree->data->arity) { + *is_valid_ret = CCS_FALSE; + return CCS_RESULT_SUCCESS; + } + tree = tree->data->children[position[i]]; + } + *is_valid_ret = CCS_TRUE; return CCS_RESULT_SUCCESS; } diff --git a/tests/test_dynamic_tree_space.c b/tests/test_dynamic_tree_space.c index da794558..352e35c5 100644 --- a/tests/test_dynamic_tree_space.c +++ b/tests/test_dynamic_tree_space.c @@ -63,7 +63,6 @@ void test_dynamic_tree_space(void) { ccs_result_t err; - ccs_bool_t is_valid; ccs_tree_t root, tree; ccs_tree_space_t tree_space; ccs_tree_space_type_t tree_type; @@ -108,16 +107,18 @@ test_dynamic_tree_space(void) assert(err == CCS_RESULT_SUCCESS); assert(values[0].value.i == 400 + 0); free(values); - err = ccs_tree_space_check_position(tree_space, 0, NULL, &is_valid); + + err = ccs_create_tree_configuration(tree_space, NULL, 0, NULL, &config); assert(err == CCS_RESULT_SUCCESS); - assert(is_valid == CCS_TRUE); + ccs_release_object(config); position = (size_t *)malloc(2 * sizeof(size_t)); position[0] = 1; position[0] = 4; - err = ccs_tree_space_check_position(tree_space, 2, position, &is_valid); - assert(err == CCS_RESULT_SUCCESS); - assert(is_valid == CCS_FALSE); + + err = ccs_create_tree_configuration( + tree_space, NULL, 2, position, &config); + assert(err == CCS_RESULT_ERROR_INVALID_VALUE); position[0] = 1; position[1] = 1; @@ -141,10 +142,6 @@ test_dynamic_tree_space(void) err = ccs_tree_space_sample(tree_space, NULL, NULL, &config); assert(err == CCS_RESULT_SUCCESS); - err = ccs_tree_space_samples( - tree_space, NULL, NULL, NUM_SAMPLES, configs); - assert(err == CCS_RESULT_SUCCESS); - char *buff; size_t buff_size; @@ -163,6 +160,10 @@ test_dynamic_tree_space(void) CCS_SERIALIZE_OPTION_END); assert(err == CCS_RESULT_SUCCESS); + err = ccs_tree_space_samples( + tree_space, NULL, NULL, NUM_SAMPLES, configs); + assert(err == CCS_RESULT_SUCCESS); + inv_sum = 0; for (size_t i = 0; i < 5; i++) { depths[i] = 0; @@ -170,10 +171,6 @@ test_dynamic_tree_space(void) } inv_sum = 1.0 / inv_sum; for (size_t i = 0; i < NUM_SAMPLES; i++) { - err = ccs_tree_space_check_configuration( - tree_space, configs[i], &is_valid); - assert(err == CCS_RESULT_SUCCESS); - assert(is_valid == CCS_TRUE); err = ccs_tree_configuration_get_position( configs[i], 0, NULL, &position_size); assert(err == CCS_RESULT_SUCCESS); @@ -215,10 +212,6 @@ test_dynamic_tree_space(void) } inv_sum = 1.0 / inv_sum; for (size_t i = 0; i < NUM_SAMPLES; i++) { - err = ccs_tree_space_check_configuration( - tree_space, configs[i], &is_valid); - assert(err == CCS_RESULT_SUCCESS); - assert(is_valid == CCS_TRUE); err = ccs_tree_configuration_get_position( configs[i], 0, NULL, &position_size); assert(err == CCS_RESULT_SUCCESS); diff --git a/tests/test_static_tree_space.c b/tests/test_static_tree_space.c index c8cd89d8..b3521861 100644 --- a/tests/test_static_tree_space.c +++ b/tests/test_static_tree_space.c @@ -145,11 +145,6 @@ test_static_tree_space(void) } inv_sum = 1.0 / inv_sum; for (size_t i = 0; i < NUM_SAMPLES; i++) { - ccs_bool_t is_valid; - err = ccs_tree_space_check_configuration( - tree_space, configs[i], &is_valid); - assert(err == CCS_RESULT_SUCCESS); - assert(is_valid == CCS_TRUE); err = ccs_tree_configuration_get_position( configs[i], 0, NULL, &position_size); assert(err == CCS_RESULT_SUCCESS); @@ -199,11 +194,6 @@ test_static_tree_space(void) } inv_sum = 1.0 / inv_sum; for (size_t i = 0; i < NUM_SAMPLES; i++) { - ccs_bool_t is_valid; - err = ccs_tree_space_check_configuration( - tree_space, configs[i], &is_valid); - assert(err == CCS_RESULT_SUCCESS); - assert(is_valid == CCS_TRUE); err = ccs_tree_configuration_get_position( configs[i], 0, NULL, &position_size); assert(err == CCS_RESULT_SUCCESS); diff --git a/tests/test_tree.c b/tests/test_tree.c index bcfa78ea..0c1141d2 100644 --- a/tests/test_tree.c +++ b/tests/test_tree.c @@ -41,7 +41,6 @@ test_tree(void) samples[NUM_SAMPLES], num_values; int counts[5]; ccs_float_t weight, bias, areas[5]; - ccs_bool_t is_valid; ccs_result_t err = CCS_RESULT_SUCCESS; // Basic creation @@ -169,10 +168,7 @@ test_tree(void) position = (size_t *)malloc(2 * sizeof(size_t)); position[0] = 2; position[1] = 1; - err = ccs_tree_position_is_valid(root, 2, position, &is_valid); - assert(err == CCS_RESULT_SUCCESS); - assert(is_valid == CCS_TRUE); - err = ccs_tree_get_node_at_position(root, 2, position, &node); + err = ccs_tree_get_node_at_position(root, 2, position, &node); assert(err == CCS_RESULT_SUCCESS); assert(grand_child == node); free(position); @@ -181,9 +177,8 @@ test_tree(void) position[0] = 2; position[1] = 1; position[2] = 3; - err = ccs_tree_position_is_valid(root, 3, position, &is_valid); - assert(err == CCS_RESULT_SUCCESS); - assert(is_valid == CCS_FALSE); + err = ccs_tree_get_node_at_position(root, 3, position, &node); + assert(err == CCS_RESULT_ERROR_OUT_OF_BOUNDS); free(position); position = (size_t *)malloc(2 * sizeof(size_t));