design: Update design.txt
Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
This commit is contained in:
parent
2b15048777
commit
54f9263170
113
design.txt
113
design.txt
|
@ -372,81 +372,108 @@ Idle queue: (lib/idle.cpp)
|
|||
|
||||
Index: (lib/index.cpp)
|
||||
An inverted index allows me to map multiple values to a single key.
|
||||
Keys are tracked separately from the rest of the map so they can be
|
||||
found and iterated over without writing ugly code.
|
||||
|
||||
- Index:
|
||||
class Index {
|
||||
private:
|
||||
map<string, set<int>>
|
||||
File filename;
|
||||
map<string, set<unsigned int>> index;
|
||||
set<string> keys;
|
||||
File file;
|
||||
public:
|
||||
Index::Index(filename);
|
||||
void load();
|
||||
void save();
|
||||
void insert(key, int);
|
||||
void delete(key, int);
|
||||
void replace(key, int);
|
||||
const set<string> &keys();
|
||||
const set<int> &operator[](string);
|
||||
void insert(key, unsigned int);
|
||||
void remove(key);
|
||||
void remove(key, unsigned int);
|
||||
const set<string>::iterator keys_begin();
|
||||
const set<string>::iterator keys_end();
|
||||
const set<unsigned int> &operator[](string);
|
||||
};
|
||||
|
||||
File << keys.size() << endl;
|
||||
File << key << endl;
|
||||
File << map[key].size() << int_0 << int_1 << ... << int_n << endl;
|
||||
|
||||
- API:
|
||||
Index.Index(filename);
|
||||
Index : Index(filename);
|
||||
Initializes an index using ~/.ocarina{-debug}K/filename. Pass
|
||||
an empty string if you do not want this index to be saved.
|
||||
Index.load();
|
||||
|
||||
void Index : load();
|
||||
Reads data from a file. Call after static initialization of
|
||||
Ocarina to ensure idle tasks are configured
|
||||
Index.save();
|
||||
|
||||
void Index : save();
|
||||
Saves data to file
|
||||
Index.insert(key, int);
|
||||
|
||||
void Index : insert(key, unsigned int);
|
||||
1) If key does not exist, create it.
|
||||
2) Add int to the list
|
||||
3) Index.save()
|
||||
Index.delete(key, int);
|
||||
2) Add int to the set for the given key
|
||||
|
||||
void Index : remove(key);
|
||||
Remove a key from the index;
|
||||
|
||||
Index : remove(key, unsigned int);
|
||||
1) Remove int from the set of values associated with key
|
||||
2) Do not delete key if set is empty
|
||||
3) Index.save()
|
||||
Index.replace(key, int)
|
||||
1) map[key].clear()
|
||||
2) insert(key, int)
|
||||
Index.keys();
|
||||
Return a set of index keys
|
||||
Index.operator[](string key);
|
||||
2) If the set is empty, remove the key
|
||||
|
||||
const set<string>::iterator void Index : keys_begin()
|
||||
Return an iterator pointing to the beginning of the keys set.
|
||||
|
||||
const set<string>::iterator void Index : keys_end()
|
||||
Return an iterator pointing to the end of the keys set.
|
||||
|
||||
Index : operator[](string key);
|
||||
Return the set associated with key
|
||||
|
||||
|
||||
|
||||
Filter: (lib/filter.cpp)
|
||||
Filtering is used to generate a subset of songs for easier searching.
|
||||
Filtering is used to generate a subset of songs displayed by the UI to
|
||||
that users can choose from. The inverted index is generated at startup
|
||||
so there is no need for a remove() function, since it will be wiped
|
||||
the next time the application starts.
|
||||
|
||||
- Index:
|
||||
map<string, string> lowercase_cache;
|
||||
map<string, set<string>> substring_cache;
|
||||
Index filter_index("");
|
||||
map<string, string> lowercase_cache;
|
||||
unsigned int lowercase_cache_hits;
|
||||
|
||||
- Parsing:
|
||||
1) Convert the provided string into a list of words, using whitespace
|
||||
and the following characters as delimiters: \/,;()_~+"
|
||||
and the following characters as delimiters: \/,;()_-~+"
|
||||
|
||||
For each word:
|
||||
2) Check the lowercase_cache to see if we have seen the word before,
|
||||
a) If we have, return the stored string
|
||||
b) Convert the string to lowercase and strip out remaining
|
||||
special characters. Add the result to the lowercase_cache;
|
||||
3) Check the substring_cache to see if we have seen the word before,
|
||||
a) If we have, use the substring set returned
|
||||
b) Break the word into substrings from the front only. For
|
||||
example: "dalek" would contain the substrings
|
||||
{d, da, dal, dale, dalek}. Add to the substring cache.
|
||||
|
||||
- API:
|
||||
filter :: add(string, track_id);
|
||||
Parses the string and adds the track_id to the index.
|
||||
void filter :: add(string, track_id);
|
||||
Parse the string into substrings following the "Parsing"
|
||||
section (above). Add each (substring, track_id) pair to the
|
||||
filter_index.
|
||||
|
||||
To generate substrings, iterate over the word starting from
|
||||
the front. For example: "dalek" would contain the substrings
|
||||
{d, da, dal, dale, dalek}.
|
||||
|
||||
void filter :: search(string, set<track_id> &);
|
||||
Parse the string and fill in the set with matching tracks.
|
||||
Parse the string into substrings following the "Parsing"
|
||||
section (above). We want to find track_ids that match ALL
|
||||
substrings, so take the intersection of all sets returned by
|
||||
the filter_index for a given substring.
|
||||
|
||||
void filter :: print_cache_stats();
|
||||
Print cache hit and size information.
|
||||
|
||||
void filter :: get_index();
|
||||
Return the index storing all the filter data.
|
||||
(Only available if -DCONFIG_TEST is set)
|
||||
|
||||
|
||||
|
||||
|
@ -769,6 +796,22 @@ Future work:
|
|||
to do the sorting.
|
||||
|
||||
- Better design file format: (6.1)
|
||||
Todo list in each document instead of all at once in the footer
|
||||
Todo list in each document instead of all at once in the footer.
|
||||
Leave the Todo list out of the official "design document" and
|
||||
keep it in each individual section instead.
|
||||
XML?
|
||||
Code formatting?
|
||||
|
||||
- Copy a song group to a different directory: (6.x)
|
||||
This can be useful for keeping an external device (like an
|
||||
Android phone) updated with the music you want to listen to.
|
||||
Complications: I have an mp3 mirror of all my music, and I
|
||||
want the mp3s to be synced. Perhaps track mirrors in Ocarina?
|
||||
|
||||
- Mirror directory: (6.x)
|
||||
I rip music to .flac, but keep an mp3 mirror directory to sync
|
||||
to other computers and phones. An Ocarina tool to manage a
|
||||
COMPLETE library mirror might be a good idea so I no longer
|
||||
need to manage it externally. This can still be done with a
|
||||
script, a cron job, and maybe a "mirror this track" option in
|
||||
the library? Perhaps create a mirror group?
|
||||
|
|
|
@ -54,6 +54,22 @@ Future work:
|
|||
to do the sorting.
|
||||
|
||||
- Better design file format: (6.1)
|
||||
Todo list in each document instead of all at once in the footer
|
||||
Todo list in each document instead of all at once in the footer.
|
||||
Leave the Todo list out of the official "design document" and
|
||||
keep it in each individual section instead.
|
||||
XML?
|
||||
Code formatting?
|
||||
|
||||
- Copy a song group to a different directory: (6.x)
|
||||
This can be useful for keeping an external device (like an
|
||||
Android phone) updated with the music you want to listen to.
|
||||
Complications: I have an mp3 mirror of all my music, and I
|
||||
want the mp3s to be synced. Perhaps track mirrors in Ocarina?
|
||||
|
||||
- Mirror directory: (6.x)
|
||||
I rip music to .flac, but keep an mp3 mirror directory to sync
|
||||
to other computers and phones. An Ocarina tool to manage a
|
||||
COMPLETE library mirror might be a good idea so I no longer
|
||||
need to manage it externally. This can still be done with a
|
||||
script, a cron job, and maybe a "mirror this track" option in
|
||||
the library? Perhaps create a mirror group?
|
||||
|
|
Loading…
Reference in New Issue