<commit_before>package com.jakway.music.song;

import com.jakway.music.Settings;
import com.jakway.music.filter.DuplicateHandler;

import org.jaudiotagger.tag.Tag;
import org.jaudiotagger.audio.generic.GenericAudioHeader;
import org.jaudiotagger.tag.FieldKey;

/**
 * This class compares songs to see if they're "duplicates"
 * This is considerably more complex than just testing each field because of typos, varying song quality, etc.
 * It's a song "key" this class can be used as a key in a map to sort songs (duplicate songs will have the same key even if the files are not the same)
 */
public class SongKey 
{
    private Song song;
    private String artist, album, title;
    private int year = -1;

    public SongKey(Song song)
    {
        this.song = song;
        Tag tag = song.getTag();
        //some formats don't require tags
        //for the formats that require tags they may still be empty tags
        if(tag != null && !tag.isEmpty())
        {
            artist = tag.getFirst(FieldKey.ARTIST);
            album = tag.getFirst(FieldKey.ALBUM);
            title = tag.getFirst(FieldKey.TITLE);
            try {
            year = Integer.parseInt(tag.getFirst(FieldKey.YEAR));
            } catch(NumberFormatException e)
            {
                //ignore the year field if it isn't well formed
                year = -1;
            }
        }
        //make any empty strings null to make comparisons and debugging easier
        if(artist != null && artist.isEmpty())
            artist = null;
        if(album != null && album.isEmpty())
            album = null;
        if(title != null && title.isEmpty())
            title = null;
    }

    public Song getSong()
    {
        return song;
    }

    /**
     * @return the artist
     */
    public String getArtist() {
        return artist;
    }

    /**
     * @return the album
     */
    public String getAlbum() {
        return album;
    }

    /**
     * @return the title
     */
    public String getTitle() {
        return title;
    }

    /**
     * @return the year
     */
    public int getYear() {
        return year;
    }

    /**
     * This test is meant to see if two music files match closely enough to be considered duplicates
     * This is NOT meant to be a strict test for equality
     * songs can be duplicates but the SongKey 
     */
    @Override
    public boolean equals(Object other)
    {
        if(!(other instanceof SongKey))
            return false;
        SongKey otherKey = (SongKey) other;

        /*
         * the maximum levenshtein distance 2 strings can differ by
         * and still be considered equal
         * not used for track length comparison because thats not a string
         */
        final int maxStringDifference = Settings.getMaxLevenshteinDistance();

        final boolean artistsMatch =  DuplicateHandler.stringsFuzzyMatch(this.getArtist(), otherKey.getArtist());
        final boolean albumsMatch = DuplicateHandler.stringsFuzzyMatch(this.getAlbum(), otherKey.getAlbum());
        final boolean titlesMatch = DuplicateHandler.stringsFuzzyMatch(this.getTitle(), otherKey.getTitle());

        if(!artistsMatch || !albumsMatch || !titlesMatch)
        {
            return false;
        }

        //compare track lengths
        //if they differ by more than the maximum specified in Settings the files are not considered equal
        int trackLengthDifference = Math.abs(this.song.getAudioHeader().getTrackLength() - otherKey.getSong().getAudioHeader().getTrackLength());
        if(trackLengthDifference > Settings.getTrackComparisonLength())
            return false;

        return true;
    }
}<commit_msg>implemented method to find if 2 songs are possible duplicates ONLY returns true for POSSIBLE duplicates certain duplicates yield false<commit_after>package com.jakway.music.song;

import com.jakway.music.Settings;
import com.jakway.music.filter.DuplicateHandler;

import org.jaudiotagger.tag.Tag;
import org.jaudiotagger.audio.generic.GenericAudioHeader;
import org.jaudiotagger.tag.FieldKey;

/**
 * This class compares songs to see if they're "duplicates"
 * This is considerably more complex than just testing each field because of typos, varying song quality, etc.
 * It's a song "key" this class can be used as a key in a map to sort songs (duplicate songs will have the same key even if the files are not the same)
 */
public class SongKey 
{
    private Song song;
    private String artist, album, title;
    private int year = -1;

    public SongKey(Song song)
    {
        this.song = song;
        Tag tag = song.getTag();
        //some formats don't require tags
        //for the formats that require tags they may still be empty tags
        if(tag != null && !tag.isEmpty())
        {
            artist = tag.getFirst(FieldKey.ARTIST);
            album = tag.getFirst(FieldKey.ALBUM);
            title = tag.getFirst(FieldKey.TITLE);
            try {
            year = Integer.parseInt(tag.getFirst(FieldKey.YEAR));
            } catch(NumberFormatException e)
            {
                //ignore the year field if it isn't well formed
                year = -1;
            }
        }
        //make any empty strings null to make comparisons and debugging easier
        if(artist != null && artist.isEmpty())
            artist = null;
        if(album != null && album.isEmpty())
            album = null;
        if(title != null && title.isEmpty())
            title = null;
    }

    public Song getSong()
    {
        return song;
    }

    /**
     * @return the artist
     */
    public String getArtist() {
        return artist;
    }

    /**
     * @return the album
     */
    public String getAlbum() {
        return album;
    }

    /**
     * @return the title
     */
    public String getTitle() {
        return title;
    }

    /**
     * @return the year
     */
    public int getYear() {
        return year;
    }

    /**
     * This test is meant to see if two music files match closely enough to be considered duplicates
     * This is NOT meant to be a strict test for equality
     * songs can be duplicates but the SongKey 
     */
    @Override
    public boolean equals(Object other)
    {
        if(!(other instanceof SongKey))
            return false;
        SongKey otherKey = (SongKey) other;

        /*
         * the maximum levenshtein distance 2 strings can differ by
         * and still be considered equal
         * not used for track length comparison because thats not a string
         */
        final int maxStringDifference = Settings.getMaxLevenshteinDistance();

        final boolean artistsMatch =  DuplicateHandler.stringsFuzzyMatch(this.getArtist(), otherKey.getArtist());
        final boolean albumsMatch = DuplicateHandler.stringsFuzzyMatch(this.getAlbum(), otherKey.getAlbum());
        final boolean titlesMatch = DuplicateHandler.stringsFuzzyMatch(this.getTitle(), otherKey.getTitle());

        if(!artistsMatch || !albumsMatch || !titlesMatch)
        {
            return false;
        }

        //compare track lengths
        //if they differ by more than the maximum specified in Settings the files are not considered equal
        int trackLengthDifference = Math.abs(this.song.getAudioHeader().getTrackLength() - otherKey.getSong().getAudioHeader().getTrackLength());
        if(trackLengthDifference > Settings.getTrackComparisonLength())
            return false;

        return true;
    }

    /**
     * Returns true ONLY if title and artist match but albums do not match
     * this method will return true ONLY for a subset of the SongKeys for which equals returns true
     * that is, not every SongKey that is equal is a possible match
     * this method exists to sort the uncertain matches from the certain ones
     */
    public boolean possibleMatch(SongKey otherKey)
    {
        final boolean artistsMatch =  DuplicateHandler.stringsFuzzyMatch(this.getArtist(), otherKey.getArtist());
        final boolean albumsMatch = DuplicateHandler.stringsFuzzyMatch(this.getAlbum(), otherKey.getAlbum());
        final boolean titlesMatch = DuplicateHandler.stringsFuzzyMatch(this.getTitle(), otherKey.getTitle());

        if(artistsMatch && titlesMatch && (!albumsMatch))
            return true;
        else
            return false;
    }
}
{'fraction_non_alphanumeric': 0.08631629354722854, 'fraction_numerical': 0.0008380222674488208, 'mean_word_length': 2.274794198353587, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7480252', 'n_tokens_mistral': 2268, 'n_tokens_neox': 2156, 'n_words': 754}