Untitled

Anonymous
plain_text
02/13/2026 2:54 AM
8.6 KB
14
Indexable
import java.io.IOException;

/**
 * Database implementation for the Songs Project.
 * Maintains two hash tables (artists and songs)
 * backed by a shared memory manager.
 *
 * @author Leguejou Awunganyi
 * @author Ishita Punna
 * @version 2026-02-12
 */
public class SongsDB implements Songs {

    /** Hash table for artist names. */
    private Hash artist;

    /** Hash table for song titles. */
    private Hash song;

    /** Shared memory manager for all strings. */
    private MemManager mem;

    /** True once the database has been initialized. */
    private boolean init = false;

    /** Initial hash table size. */
    private int initHashSize;

    /** Initial memory manager size. */
    private int initMemSize;

    /**
     * Default constructor.
     * Database must be initialized using create().
     */
    public SongsDB() {
        // Constructor does not allocate tables until create() is called
        // This allows delayed initialization from command input
    }

    /**
     * Initialize or reinitialize the database.
     *
     * @param inHash initial hash table size
     * @param inMemMan initial memory manager size
     * @return error message if invalid, otherwise empty string
     */
    public String create(int inHash, int inMemMan) {

        // Validate that hash table size is a positive value
        if (inHash <= 0) {
            return "Initial hash table size must be positive";
        }

        // Validate that memory manager size is also positive
        if (inMemMan <= 0) {
            return "Initial memory manager size must be positive";
        }

        // Memory pool size must be a power of two for buddy allocation
        if ((inMemMan & (inMemMan - 1)) != 0) {
            return "Initial memory manager size must be a power of 2";
        }

        // Save the initial sizes so clear() can reset properly
        initHashSize = inHash;
        initMemSize = inMemMan;

        // Create shared memory manager and both hash tables
        mem = new MemManager(inMemMan);
        artist = new Hash(inHash, mem);
        song = new Hash(inHash, mem);

        // Mark database as ready for operations
        init = true;
        return "";
    }

    /**
     * Reset the database to original sizes.
     *
     * @return true if cleared successfully
     */
    public boolean clear() {

        // Cannot clear unless the database was initialized first
        if (!init) {
            return false;
        }

        // Rebuild memory manager and hash tables using original sizes
        mem = new MemManager(initMemSize);
        artist = new Hash(initHashSize, mem);
        song = new Hash(initHashSize, mem);

        // Clearing always succeeds once initialized
        return true;
    }

    /**
     * Insert an artist and song pair.
     *
     * @param artistStr artist string
     * @param songStr song string
     * @return formatted status message
     */
    public String insert(String artistStr, String songStr) {

        // Ensure the database exists before inserting anything
        if (!init) {
            return "Database not initialized";
        }

        // Reject null or empty artist/song inputs
        if (artistStr == null || songStr == null
            || artistStr.isEmpty() || songStr.isEmpty()) {
            return "Input strings cannot be null or empty";
        }

        // Build output message for both insert operations
        StringBuilder sb = new StringBuilder();

        // Insert artist into the artist hash table
        String artistMsg = artist.insert(artistStr, "Artist");

        // Append memory expansion notice if pool grew
        String expanded = mem.getExpandMessage();
        if (!expanded.isEmpty()) {
            sb.append(expanded);
        }

        // Append the artist insertion result
        sb.append(artistMsg).append("\r\n");

        // Insert song into the song hash table
        String songMsg = song.insert(songStr, "Song");

        // Append expansion message again if song insert triggered growth
        expanded = mem.getExpandMessage();
        if (!expanded.isEmpty()) {
            sb.append(expanded);
        }

        // Append final song insertion result
        sb.append(songMsg);

        return sb.toString();
    }

    /**
     * Remove from either artist or song table.
     *
     * @param type table type ("artist" or "song")
     * @param name string to remove
     * @return result message
     */
    public String remove(String type, String name)
        throws IOException {

        // Database must be initialized before removal is allowed
        if (!init) {
            return "Database not initialized";
        }

        // Validate removal parameters are not null or empty
        if (type == null || name == null
            || type.isEmpty() || name.isEmpty()) {
            return "Input strings cannot be null or empty";
        }

        // Remove from the artist hash table if requested
        if (type.equalsIgnoreCase("artist")) {
            return artist.remove(name, "Artist");
        }

        // Remove from the song hash table if requested
        if (type.equalsIgnoreCase("song")) {
            return song.remove(name, "Song");
        }

        // If type is invalid, return error message
        return "Bad type value |" + type + "| on remove";
    }

    /**
     * Print database contents.
     *
     * @param type "artist", "song", or "blocks"
     * @return formatted output string
     */
    public String print(String type)
        throws IOException {

        // Printing is not allowed until database has been created
        if (!init) {
            return "Database not initialized";
        }

        // Validate print type input string
        if (type == null || type.isEmpty()) {
            return "Input strings cannot be null or empty";
        }

        // Print artist hash table contents
        if (type.equalsIgnoreCase("artist")) {
            return artist.print("artist");
        }

        // Print song hash table contents
        if (type.equalsIgnoreCase("song")) {
            return song.print("song");
        }

        // Print free memory blocks from memory manager
        if (type.equalsIgnoreCase("blocks")) {
            return mem.printBlocks();
        }

        // Invalid print type provided
        return "Bad print parameter";
    }
}
Editor is loading...
Leave a Comment