-
Notifications
You must be signed in to change notification settings - Fork 18
InMemPagedTRS handles concurrency. #855
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,6 +24,7 @@ | |
| import java.net.URI; | ||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
| import java.util.concurrent.CopyOnWriteArrayList; | ||
|
|
||
| import org.eclipse.lyo.oslc4j.core.annotation.OslcDescription; | ||
| import org.eclipse.lyo.oslc4j.core.annotation.OslcHidden; | ||
|
|
@@ -47,14 +48,14 @@ | |
| * | ||
| * {@code | ||
| * <https://.../baseResources> | ||
| * a ldp:Container; | ||
| * trs:cutoffEvent <urn:urn-3:cm1.example.com:2010-10-27T17:39:31.000Z:101> ; | ||
| * rdfs:member <http://cm1.example.com/bugs/1> ; | ||
| * rdfs:member <http://cm1.example.com/bugs/2> ; | ||
| * rdfs:member <http://cm1.example.com/bugs/3> ; | ||
| * ... | ||
| * rdfs:member <http://cm1.example.com/bugs/199> ; | ||
| * rdfs:member <http://cm1.example.com/bugs/200> . | ||
| * a ldp:Container; | ||
| * trs:cutoffEvent <urn:urn-3:cm1.example.com:2010-10-27T17:39:31.000Z:101> ; | ||
| * rdfs:member <http://cm1.example.com/bugs/1> ; | ||
| * rdfs:member <http://cm1.example.com/bugs/2> ; | ||
| * rdfs:member <http://cm1.example.com/bugs/3> ; | ||
| * ... | ||
| * rdfs:member <http://cm1.example.com/bugs/199> ; | ||
| * rdfs:member <http://cm1.example.com/bugs/200> . | ||
| * } | ||
| * </pre> | ||
| * | ||
|
|
@@ -70,9 +71,9 @@ | |
| * <pre> | ||
| * {@code | ||
| * <https://.../baseResources/page1> | ||
| * a ldp:Page; | ||
| * ldp:pageOf <https://.../baseResource>; | ||
| * ldp:nextPage <https://../baseResources/page2> . | ||
| * a ldp:Page; | ||
| * ldp:pageOf <https://.../baseResource>; | ||
| * ldp:nextPage <https://../baseResources/page2> . | ||
| * } | ||
| * </pre> | ||
| * | ||
|
|
@@ -130,65 +131,66 @@ | |
| @OslcName(LDP_TERM_CONTAINER) | ||
| @OslcResourceShape(title = "Tracked Resource Set Base Shape", describes = LDP_CONTAINER) | ||
| public class Base extends AbstractResource { | ||
| private List<URI> members; | ||
| private URI cutoffEvent; | ||
| private Page nextPage; | ||
| private final List<URI> members = new CopyOnWriteArrayList<>(); // thread-safe | ||
| private URI cutoffEvent; | ||
| private Page nextPage; | ||
|
|
||
| /** | ||
| * @return the members | ||
| */ | ||
| @OslcName(RDFS_TERM_MEMBER) | ||
| @OslcDescription("A member Resource of the Resource Set.") | ||
| @OslcPropertyDefinition(RDFS_MEMBER) | ||
| @OslcTitle("Member") | ||
| public List<URI> getMembers() { | ||
| if(members == null){ | ||
| members = new ArrayList<>(); | ||
| } | ||
| return members; | ||
| } | ||
| /** | ||
| * @return the members | ||
| */ | ||
| @OslcName(RDFS_TERM_MEMBER) | ||
| @OslcDescription("A member Resource of the Resource Set.") | ||
| @OslcPropertyDefinition(RDFS_MEMBER) | ||
| @OslcTitle("Member") | ||
| public List<URI> getMembers() { | ||
|
||
| return members; | ||
| } | ||
|
|
||
| /** | ||
| * @param members the members to set | ||
| */ | ||
| public void setMembers(List<URI> members) { | ||
| this.members = members; | ||
| } | ||
| /** | ||
| * @param members the members to set | ||
| */ | ||
| public void setMembers(List<URI> members) { | ||
| if (members == null) { | ||
| throw new IllegalArgumentException("Members list must not be null"); | ||
| } | ||
| this.members.clear(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This does not seem thread safe. As no lock is used, there could be a case where a reader would observe an empty list while this update is going on. Can we not just introduce an api to add an item? Otherwise it's best to mark this method synchronised. |
||
| this.members.addAll(members); | ||
| } | ||
|
|
||
| /** | ||
| * @return the cutoffIdentifier | ||
| */ | ||
| @OslcName(TRS_TERM_CUTOFFEVENT) | ||
| @OslcDescription("The most recent Change Log entry that is accounted for in this Base. When rdf:nil, the Base is an enumeration at the start of time.") | ||
| @OslcPropertyDefinition(TRS_CUTOFFEVENT) | ||
| @OslcTitle("Cutoff Event") | ||
| public URI getCutoffEvent() { | ||
| return cutoffEvent; | ||
| } | ||
| /** | ||
| * @param cutoffEvent the cutoffEvent to set | ||
| */ | ||
| public void setCutoffEvent(URI cutoffEvent) { | ||
| this.cutoffEvent = cutoffEvent; | ||
| } | ||
| /** | ||
| * @return the cutoffIdentifier | ||
| */ | ||
| @OslcName(TRS_TERM_CUTOFFEVENT) | ||
| @OslcDescription("The most recent Change Log entry that is accounted for in this Base. When rdf:nil, the Base is an enumeration at the start of time.") | ||
| @OslcPropertyDefinition(TRS_CUTOFFEVENT) | ||
| @OslcTitle("Cutoff Event") | ||
| public URI getCutoffEvent() { | ||
| return cutoffEvent; | ||
| } | ||
| /** | ||
| * @param cutoffEvent the cutoffEvent to set | ||
| */ | ||
| public void setCutoffEvent(URI cutoffEvent) { | ||
| this.cutoffEvent = cutoffEvent; | ||
| } | ||
|
|
||
| /** | ||
| * Return a Page object containing information about the next base page. | ||
| * The OslcHidden annotation works around a limitation in OSLC4J. If we do | ||
| * not hide the nextPage variable we get an incorrect ldp:nextPage reference | ||
| * in the Base. | ||
| * | ||
| * @return the nextPage | ||
| */ | ||
| @OslcHidden(value=true) | ||
| public Page getNextPage() { | ||
| return nextPage; | ||
| } | ||
| /** | ||
| * Return a Page object containing information about the next base page. | ||
| * The OslcHidden annotation works around a limitation in OSLC4J. If we do | ||
| * not hide the nextPage variable we get an incorrect ldp:nextPage reference | ||
| * in the Base. | ||
| * | ||
| * @return the nextPage | ||
| */ | ||
| @OslcHidden(value=true) | ||
| public Page getNextPage() { | ||
| return nextPage; | ||
| } | ||
|
|
||
| /** | ||
| * @param nextPage the nextPage to set | ||
| */ | ||
| public void setNextPage(Page nextPage) { | ||
| this.nextPage = nextPage; | ||
| } | ||
| /** | ||
| * @param nextPage the nextPage to set | ||
| */ | ||
| public void setNextPage(Page nextPage) { | ||
| this.nextPage = nextPage; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -85,7 +85,7 @@ public static List<ChangeEvent> optimizedChangesList(List<ChangeLog> changeLogs, | |
|
|
||
| // sort the events, needed for the cut-off later | ||
| firstChangelogEvents.sort(Comparator.comparing(ChangeEvent::getOrder)); | ||
| firstChangeLog.setChange(firstChangelogEvents); | ||
| firstChangeLog.setChange(new ArrayList<>(firstChangelogEvents)); | ||
|
|
||
| // TODO Andrew@2018-02-28: just delete this line, getter after setter is some superstition | ||
| // firstChangelogEvents = firstChangeLog.getChange(); | ||
|
|
@@ -100,8 +100,8 @@ public static List<ChangeEvent> optimizedChangesList(List<ChangeLog> changeLogs, | |
| } | ||
| } | ||
|
|
||
| firstChangelogEvents = firstChangelogEvents.subList(indexOfSync + 1, | ||
| firstChangelogEvents.size()); | ||
| firstChangelogEvents = new ArrayList<>(firstChangelogEvents.subList(indexOfSync + 1, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don’t like this, it's really prone to misuse. I can see how a user may forget to do this and get occasional concurrency issues.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also think that copy on write list AND a new arraylist are quite wasteful when used together? |
||
| firstChangelogEvents.size())); | ||
| firstChangeLog.setChange(firstChangelogEvents); | ||
|
|
||
| List<ChangeEvent> changesToProcess = new ArrayList<>(); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we update this signature to return a readonly list? To stop the pattern of getting a list and then modifying it by hand.