-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Fix for issue #10418 - Added the ability to focus on the most viewed entries #12077
base: main
Are you sure you want to change the base?
Conversation
# Conflicts: # src/main/java/org/jabref/gui/LibraryTab.java
try { | ||
Files.createDirectories(userDataDir); | ||
} catch (IOException e) { | ||
// Update this for more elegant error handling |
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.
AI generated. Pleasemwork on this
int currentCount = viewCounts.getOrDefault(uniqueKey, 0); | ||
viewCounts.put(uniqueKey, currentCount + 1); | ||
lastViewTimestamps.put(uniqueKey, currentTime); | ||
mvStore.commit(); // Save changes |
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.
AI comment. Delete.
String uniqueKey = PopularityGroup.getUniqueKeyForEntry(entry); | ||
long lastViewTime = lastViewTimestamps.getOrDefault(uniqueKey, 0L); | ||
|
||
if (currentTime - lastViewTime >= 3600000 && EntryTabViewModel.trackViewsProperty().get()) { // 3600000 milliseconds in one hour |
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.
Introduce constant
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.
You can also use java.time.Duration
.
@@ -7,6 +7,7 @@ | |||
import java.util.Objects; | |||
import java.util.Optional; | |||
import java.util.Random; | |||
import java.util.concurrent.locks.ReentrantLock; |
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.
what is this useful for?
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.
Sorry about that, I was having issues with file locks earlier in development and forgot to remove the import and some variables I never used.
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.
The architecture of the functionality should be changed: MVStore life cycle should be handled by the tab (and passed down to the group). See AIIndexer or SearchIndex how it could work. -- You also persist data across sessions: Thus, you will have a simlar functionality.
I do not know why ""%Group containing entries cited in a given TeX file" sneaked in. I did not find functionality about that.
/** | ||
* Takes an entry and increments the number of times it has been viewed by 1. | ||
*/ |
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.
It does more - there is a kind of if
MVMap<String, Integer> viewCounts = mvStore.openMap("entryViewCounts"); | ||
MVMap<String, Long> lastViewTimestamps = mvStore.openMap("lastViewTimestamps"); |
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.
Nono - the map is a class variable - no need to open the map each time for writing.
You need to shut down the mvstore when the tab is closed.
The the lifecycle of the AiService or search for examples.
String uniqueKey = PopularityGroup.getUniqueKeyForEntry(entry); | ||
long lastViewTime = lastViewTimestamps.getOrDefault(uniqueKey, 0L); | ||
|
||
if (currentTime - lastViewTime >= ONE_HOUR_IN_MILLISECONDS && EntryTabViewModel.trackViewsProperty().get()) { |
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.
The check for the property is too late - everything doesn't need to be done if the property is false.
int currentCount = viewCounts.getOrDefault(uniqueKey, 0); | ||
viewCounts.put(uniqueKey, currentCount + 1); | ||
lastViewTimestamps.put(uniqueKey, currentTime); | ||
mvStore.commit(); |
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.
I think, the commit happens automatically.
*/ | ||
private void incrementViewCount(BibEntry entry) { | ||
MVStore mvStore = PopularityGroup.getMVStore(); | ||
synchronized (mvStore) { |
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.
if the maps are opened after load, there is no need for synchronized
(see below)
* @return The number of views for the BibEntry, or 0 if not found. | ||
*/ | ||
public static int getEntryViewCount(BibEntry entry) { | ||
MVMap<String, Integer> viewCounts = mvStore.openMap("entryViewCounts"); |
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.
Please try to make that a class variable. It is passed from the library tab on creation.
public static String getUniqueKeyForEntry(BibEntry entry) { | ||
return entry.getField(StandardField.DOI).orElse( | ||
entry.getField(StandardField.KEY).orElse( | ||
String.valueOf(entry.hashCode()) | ||
) | ||
); | ||
} |
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.
Remove --> use org.jabref.model.entry.BibEntry#getId
instead.
public static synchronized MVStore getMVStore() { | ||
if (mvStore == null) { | ||
Path mvStorePath = getOtherDataDir().resolve("tracking.mv"); | ||
mvStore = new MVStore.Builder().fileName(mvStorePath.toString()).open(); | ||
} | ||
return mvStore; | ||
} |
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.
MVStore should be passed by caller.
private long getTimeThreshold(long currentTime, String selectedTimePeriod) { | ||
return switch (selectedTimePeriod) { | ||
case "Last week" -> | ||
currentTime - 7 * 24 * 60 * 60 * 1000L; | ||
case "Last month" -> | ||
currentTime - 30 * 24 * 60 * 60 * 1000L; | ||
case "Last year" -> | ||
currentTime - 365 * 24 * 60 * 60 * 1000L; | ||
default -> // "All time" | ||
0; | ||
}; | ||
} |
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.
The factor should be stored upon group creation (I think on change of group properties, the group is re-created)
Always reading the property seems to slow down things.
|
||
|
||
|
||
<CheckBox fx:id="enableViewTracking" text="%Enable user behaviour analysis"/> |
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.
Enable user behaviour analysis
--> wrong word - please try to use the same words "view tracking" below "popularity" is OK, but "bheavior analysis" is even more general. It should be consistent with src/main/java/org/jabref/gui/groups/GroupDialog.fxml.
Thanks for your review @koppor, I have exams coming up so i'll need to take a break from working on this for the next two-ish weeks, but im committed to getting this done :) Sorry for all the mess, it's my first time contributing to a project like this. |
} | ||
|
||
public List<BibEntry> processPopularityGroup(List<BibEntry> allEntries, String timePeriodCombo, Integer maxEntriesCombo) { | ||
List<BibEntry> filteredEntries = 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.
Let's call this popularEntries for consistency.
Describe the changes you have made here:
Closes #10418
Mandatory checks
CHANGELOG.md
described in a way that is understandable for the average user (if applicable)Issues with my implementation: