Mercurial > repos > public > sbplib
changeset 9:6b9b2283e7ed
Added class for handleing .mat files as a key-value store.
author | Jonatan Werpers <jonatan@werpers.com> |
---|---|
date | Mon, 21 Sep 2015 17:41:18 +0200 |
parents | 67ab7fd8054c |
children | 9551f4e7cb66 |
files | SolutionFile.m |
diffstat | 1 files changed, 155 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SolutionFile.m Mon Sep 21 17:41:18 2015 +0200 @@ -0,0 +1,155 @@ +classdef SolutionFile < handle + properties + filename + matfile + % keyHeaders + keys % Cell array of keys. Each key is a structure + % entries + end + + methods + function obj = SolutionFile(filename) + + obj.filename = filename; + + is_new_file = ~exist(filename,'file'); + + obj.matfile = matfile(filename,'Writable',true); + + if is_new_file + obj.matfile.keys = {}; + obj.matfile.entries = {}; + end + + % obj.keyHeaders = obj.matfile.keyHeaders; + obj.keys = obj.matfile.keys; + + end + + function list(obj, show_syntax) + default_arg('show_syntax',false); + for i = 1:length(obj.keys) + fprintf('[%d]: %s', i, struct2string(obj.keys{i})); + + if show_syntax + fprintf('\t%s',struct2syntax(obj.keys{i})); + end + + fprintf('\n'); + end + end + + % Returns the index for a key. Returns 0 if the key doesn't exist + function I = getIndex(obj, key) + I = 0; + + for i = 1:length(obj.keys) + if isequal(key,obj.keys{i}); + I = i; + return + end + end + end + + function b = isKey(obj, key) + I = obj.getIndex(key); + + if I == 0 + b = false; + else + b = true; + end + end + + % Gets entries where key match exactly. + function e = get(obj, key) + if ~obj.isKey(key); + error('No such key: %s', struct2string(key)); + end + + I = obj.getIndex(key); + e = getEntryByIndex(I); % unpack the cell array + end + + + % Handles indexing weirdness of matfile class + function e = getEntryByIndex(obj, I) + e = obj.matfile.entries(1,I); + e = e{1}; + end + + function e = deleteByIndex(obj, I) + obj.keys(I) = []; + obj.matfile.keys = obj.keys; + + entries = obj.matfile.entries; + entries(I) = []; + obj.matfile.entries = entries; + end + + % Handles indexing weirdness of matfile class + function setEntryByIndex(obj,I, entry, force_flag) + default_arg('force_flag',false); + if ~force_flag && ( I < 1 || I > length(obj.keys)) + error('I is out of range. I = %d',I); + end + obj.matfile.entries(1,I) = {entry}; + end + + function store(obj, key, entry) + if obj.isKey(key); + I = obj.getIndex(key); + else + I = length(obj.keys) + 1; + end + + obj.keys{I} = key; + obj.matfile.keys = obj.keys; + obj.setEntryByIndex(I,entry,true); + end + + function delete(obj, key) + if ~obj.isKey(key); + error('No such key: %s', struct2string(key)); + end + I = obj.getIndex(key); + obj.deleteByIndex(I); + end + + + + % Gets entries where the defined parts of partial_key matches the key of the entry + function [keys, entries] = find(obj,partial_key) + keys = {}; + entries = {}; + for i = 1:length(obj.keys) + if structIsSubset(partial_key,obj.keys{i}) + i + obj.keys{i} + keys{end + 1} = obj.keys{i}; + entries{end + 1} = obj.getEntryByIndex(i); + end + end + + + % Returns true if the the fields of struct a exists in A and have the same values + function b = structIsSubset(a,A) + fn = fieldnames(a); + + b = true; % if a has no filds + for j = 1:length(fn) + fname = fn{j}; + value = a.(fname); + if isfield(A,fname) && a.(fname) == A.(fname) + b = true; + continue; + else + b = false; + break; + end + end + end + end + end + +end \ No newline at end of file