Skip to content

Document the sharing map, and move sharing map unit tests to catch #1899

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
May 17, 2018

Conversation

danpoe
Copy link
Contributor

@danpoe danpoe commented Mar 1, 2018

No description provided.

@danpoe danpoe requested a review from smowton March 1, 2018 17:24
@danpoe danpoe force-pushed the sharing-map-catch-unit-tests branch from 9547dde to ed0918d Compare March 1, 2018 18:07
@tautschnig
Copy link
Collaborator

Build failures are genuine:

../src/util/sharing_map.h:486:15: error: unused variable 'c' [-Werror,-Wunused-variable]

It seems that necessitates some changes to sharing_mapt. While at that: would it be possible to please add some documentation that in particular covers 1) complexity of operations and 2) reference counting/garbage collection semantics?

@danpoe
Copy link
Contributor Author

danpoe commented Mar 2, 2018

@tautschnig Ok, I'll add some documentation.

@danpoe danpoe force-pushed the sharing-map-catch-unit-tests branch from ed0918d to f721a5f Compare March 2, 2018 10:53
@danpoe danpoe force-pushed the sharing-map-catch-unit-tests branch from f721a5f to 88ac580 Compare March 5, 2018 16:30
@danpoe danpoe changed the title Move sharing map unit tests to catch Document the sharing map, and move sharing map unit tests to catch Mar 5, 2018
@danpoe danpoe force-pushed the sharing-map-catch-unit-tests branch from 88ac580 to f2afe15 Compare March 5, 2018 18:25
@hannes-steffenhagen-diffblue
Copy link
Contributor

unit/sharing_map.cpp is currently excluded from the cmake build (unit/CMakeLists.txt, line 11).

Also, the test for sharing_map and sharing_node should probably be under the unit/util directory.

unit/Makefile Outdated
@@ -28,6 +28,7 @@ SRC += unit_tests.cpp \
java_bytecode/inherited_static_fields/inherited_static_fields.cpp \
pointer-analysis/custom_value_set_analysis.cpp \
sharing_node.cpp \
sharing_map.cpp \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @hannes-steffenhagen-diffblue said: these should likely go in the util folder.

@@ -450,7 +450,7 @@ SHARING_MAPT2(, size_type)::erase(
return 0;

node_type *del=nullptr;
unsigned del_bit;
unsigned del_bit=0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure unsigned should not be used here at all and any such use should be a std::size_t instead.

///
/// When inserting a key-value pair into the map, first the hash of its key is
/// computed. The `bits` number of lower order bits of the hash are deemed
/// significant, and are grouped into `bits` / `chunk` chunks). The hash is then
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ) does not have a matching opening parenthesis.

/// purposes of determining the position of the key-value pair in the trie. The
/// actual key-value pairs are stored in the leaf nodes. Collisions (i.e., two
/// different keys yield the same "string"), are handled by chaining the
/// corresponding key-value pairs in a `std::list`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would a std::forward_list be sufficient?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is fixed in an upcoming PR.

@@ -39,6 +39,66 @@ Author: Daniel Poetzl
CV typename sharing_mapt<keyT, valueT, hashT, predT>::ST \
sharing_mapt<keyT, valueT, hashT, predT>

/// A map implemented as a tree where subtrees can be shared between different
/// maps.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you somewhere explain how to generate sharing (likely via copy and/or assignment operations)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'll add an explanation for that.

@tautschnig
Copy link
Collaborator

Is is possible to add iterator and const_iterator members, or actually provide the same interface that a std::map provides?

@danpoe
Copy link
Contributor Author

danpoe commented Apr 23, 2018

A few differences between the interfaces of sharing_mapt and std::map are necessary I think. I'd like to avoid having methods return/take iterators for the reasons below.

std::map is implemented as an RB tree, consisting of nodes that also have pointers to their parents. An iterator thus just needs to keep a pointer to a node. In our tree the nodes do not have parent pointers. An iterator would thus need to keep a stack of parent pointers. Moreover, dereferencing a std::map iterator yields a std::pair, which matches the implementation of std::map which stores key-value pairs as std::pair's internally, whereas sharing_mapt does not store them as std::pair's.

Since an iterator would need to contain a stack, it would cause unnecessary overhead to return an iterator on e.g. a call to find(). The iterator would also be less useful than a std::map iterator:

  • The elements are not stored in any particular order in sharing_mapt, thus idioms like first retrieving an iterator with find() and then starting to iterate from that position are not meaningful.
  • Passing an iterator to e.g. insert() in addition to a key as a hint would not be more efficient than just using the key, as when the map is modified all nodes on the path from the root of the tree to the newly inserted element need to be copied if they have use_count > 1 (thus a traversal from the root to the insert position needs to be done in any case).
  • Using an iterator (i.e. not a const_iterator) to iterate over sharing_mapt would break all the sharing as it would copy all the shared nodes on the assumption that they may be modified which is likely undesirable.

@danpoe danpoe force-pushed the sharing-map-catch-unit-tests branch 2 times, most recently from 5f35d26 to ca9906e Compare April 23, 2018 17:03
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

@danpoe
Copy link
Contributor Author

danpoe commented May 17, 2018

@tautschnig Would you mind if we merge this PR? (it's documentation, plus unit test refactoring, and some smaller fixes). We can move potential further discussions to #2126 or another upcoming PR.

@tautschnig
Copy link
Collaborator

Looking.

@tautschnig tautschnig merged commit 9fe432b into diffblue:develop May 17, 2018
@danpoe danpoe deleted the sharing-map-catch-unit-tests branch June 2, 2020 17:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants