23 #ifndef KALDI_UTIL_KALDI_TABLE_INL_H_ 24 #define KALDI_UTIL_KALDI_TABLE_INL_H_ 46 typedef typename Holder::T
T;
49 virtual bool Open(
const std::string &rxfilename) = 0;
52 virtual bool Done()
const = 0;
55 virtual bool IsOpen()
const = 0;
58 virtual std::string
Key() = 0;
63 virtual T &
Value() = 0;
67 virtual void Next() = 0;
70 virtual bool Close() = 0;
77 virtual void SwapHolder(Holder *other_holder) = 0;
89 typedef typename Holder::T
T;
95 virtual bool Open(
const std::string &rspecifier) {
96 if (state_ != kUninitialized && state_ != kError)
98 KALDI_ERR <<
"Error closing previous input: " 99 <<
"rspecifier was " << rspecifier_;
101 rspecifier_ = rspecifier;
105 if (!script_input_.Open(script_rxfilename_, &binary)) {
108 state_ = kUninitialized;
112 KALDI_WARN <<
"Script file should not be binary file.";
118 if (state_ == kError)
129 case kEof:
case kHaveScpLine:
case kHaveObject:
case kHaveRange:
131 case kUninitialized:
case kError:
133 default:
KALDI_ERR <<
"IsOpen() called on invalid object.";
142 case kHaveScpLine:
case kHaveObject:
case kHaveRange:
return false;
143 case kEof:
case kError:
return true;
145 default:
KALDI_ERR <<
"Done() called on TableReader object at the wrong" 151 virtual std::string
Key() {
154 case kHaveScpLine:
case kHaveObject:
case kHaveRange:
break;
157 KALDI_ERR <<
"Key() called on TableReader object at the wrong time.";
163 if (!EnsureObjectLoaded())
164 KALDI_ERR <<
"Failed to load object from " 166 <<
" (to suppress this error, add the permissive " 167 <<
"(p, ) option to the rspecifier.";
171 if (state_ == kHaveRange) {
172 return range_holder_.Value();
175 return holder_.Value();
180 if (state_ == kHaveObject) {
182 state_ = kHaveScpLine;
183 }
else if (state_ == kHaveRange) {
184 range_holder_.Clear();
185 state_ = kHaveObject;
187 KALDI_WARN <<
"FreeCurrent called at the wrong time.";
198 if (state_ == kHaveObject) {
199 holder_.Swap(other_holder);
200 state_ = kHaveScpLine;
201 }
else if (state_ == kHaveRange) {
202 range_holder_.Swap(other_holder);
203 state_ = kHaveObject;
227 if (opts_.permissive) {
230 if (EnsureObjectLoaded())
return;
246 if (script_input_.IsOpen())
247 status = script_input_.Close();
248 if (data_input_.IsOpen())
250 range_holder_.Clear();
253 KALDI_ERR <<
"Close() called on input that was not open.";
255 state_ = kUninitialized;
256 if (old_state == kError || (old_state == kEof && status != 0)) {
257 if (opts_.permissive) {
258 KALDI_WARN <<
"Close() called on scp file with read error, ignoring the" 259 " error because permissive mode specified.";
279 KALDI_ERR <<
"TableReader: reading script file failed: from scp " 297 if (!(state_ == kHaveScpLine || state_ == kHaveObject ||
298 state_ == kHaveRange))
299 KALDI_ERR <<
"Invalid state (code error)";
301 if (state_ == kHaveScpLine) {
304 if (Holder::IsReadInBinary()) {
305 ans = data_input_.Open(data_rxfilename_, NULL);
307 ans = data_input_.OpenTextMode(data_rxfilename_);
314 if (holder_.Read(data_input_.Stream())) {
315 state_ = kHaveObject;
325 if (range_.empty()) {
332 if (state_ == kHaveRange) {
339 if (!range_holder_.ExtractRange(holder_, range_)) {
342 <<
"[" << range_ <<
"]";
352 script_input_.Close();
355 range_holder_.Clear();
364 range_holder_.Clear();
365 state_ = kHaveObject;
367 case kHaveScpLine:
case kHaveObject:
case kFileStart:
break;
370 KALDI_ERR <<
"Reading script file: Next called wrongly.";
374 if (getline(script_input_.Stream(), line)) {
379 std::string data_rxfilename, rest;
381 if (!key_.empty() && !rest.empty()) {
383 if (rest[rest.size()-1] ==
']') {
385 KALDI_WARN <<
"Reading rspecifier '" << rspecifier_
386 <<
", cannot make sense of scp line " 392 data_rxfilename = rest;
395 bool filenames_equal = (data_rxfilename_ == data_rxfilename);
396 if (!filenames_equal)
397 data_rxfilename_ = data_rxfilename;
398 if (state_ == kHaveObject) {
399 if (!filenames_equal) {
401 state_ = kHaveScpLine;
406 state_ = kHaveScpLine;
409 KALDI_WARN <<
"We got an invalid line in the scp file. " 410 <<
"It should look like: some_key 1.ark:10, got: " 417 script_input_.Close();
418 if (data_input_.IsOpen())
421 range_holder_.Clear();
486 typedef typename Holder::T
T;
490 virtual bool Open(
const std::string &rspecifier) {
491 if (state_ != kUninitialized) {
493 if (opts_.permissive)
495 "(only warning, since permissive mode).";
497 KALDI_ERR <<
"Error closing previous input.";
500 rspecifier_ = rspecifier;
502 &archive_rxfilename_,
508 if (Holder::IsReadInBinary())
509 ans = input_.Open(archive_rxfilename_, NULL);
511 ans = input_.OpenTextMode(archive_rxfilename_);
515 state_ = kUninitialized;
520 if (state_ == kError) {
521 KALDI_WARN <<
"Error beginning to read archive file (wrong filename?): " 524 state_ = kUninitialized;
536 case kFileStart:
case kFreedObject:
541 std::istream &is = input_.Stream();
557 if ((c = is.peek()) !=
' ' && c !=
'\t' && c !=
'\n') {
562 KALDI_WARN <<
"Invalid archive file format: expected space after key " 563 << key_ <<
", got character " 564 <<
CharToString(static_cast<char>(is.peek())) <<
", reading " 569 if (c !=
'\n') is.get();
570 if (holder_.Read(is)) {
571 state_ = kHaveObject;
574 KALDI_WARN <<
"Object read failed, reading archive " 583 case kEof:
case kError:
case kHaveObject:
case kFreedObject:
return true;
584 case kUninitialized:
return false;
585 default:
KALDI_ERR <<
"IsOpen() called on invalid object.";
595 case kEof:
case kError:
599 KALDI_ERR <<
"Done() called on TableReader object at the wrong time.";
604 virtual std::string
Key() {
607 case kHaveObject:
break;
610 KALDI_ERR <<
"Key() called on TableReader object at the wrong time.";
621 KALDI_ERR <<
"Value() called on TableReader object at the wrong time.";
623 return holder_.Value();
627 if (state_ == kHaveObject) {
629 state_ = kFreedObject;
631 KALDI_WARN <<
"FreeCurrent called at the wrong time.";
639 if (state_ == kHaveObject) {
640 holder_.Swap(other_holder);
641 state_ = kFreedObject;
643 KALDI_ERR <<
"SwapHolder called at the wrong time " 644 "(error related to ',bg' modifier).";
653 KALDI_ERR <<
"Close() called on TableReader twice or otherwise wrongly.";
656 status = input_.Close();
657 if (state_ == kHaveObject)
660 state_ = kUninitialized;
661 if (old_state == kError || (old_state == kEof && status != 0)) {
662 if (opts_.permissive) {
663 KALDI_WARN <<
"Error detected closing TableReader for archive " 666 <<
"it as permissive mode specified.";
678 KALDI_ERR <<
"TableReader: error detected closing archive " 701 template<
class Holder>
705 typedef typename Holder::T
T;
709 base_reader_(base_reader) {}
714 virtual bool Open(
const std::string &rxfilename) {
716 base_reader_->IsOpen());
722 if (!base_reader_->Done())
730 return base_reader_ != NULL;
738 while (base_reader_ != NULL && !base_reader_->Done()) {
739 consumer_sem_.Signal();
743 producer_sem_.Wait();
746 if (base_reader_ != NULL)
747 base_reader_->Next();
751 consumer_sem_.Signal();
753 consumer_sem_.Signal();
759 if (base_reader_->IsOpen()) {
760 base_reader_->Close();
764 consumer_sem_.Signal();
769 object->RunInBackground();
774 virtual std::string
Key() {
776 KALDI_ERR <<
"Calling Key() at the wrong time.";
781 KALDI_ERR <<
"Calling Value() at the wrong time.";
782 return holder_.Value();
785 KALDI_ERR <<
"SwapHolder() should not be called on this class.";
789 KALDI_ERR <<
"Calling FreeCurrent() at the wrong time.";
798 consumer_sem_.Wait();
799 if (base_reader_ == NULL || !base_reader_->IsOpen())
800 KALDI_ERR <<
"Error detected (likely code error) in background " 801 <<
"reader (',bg' option)";
802 if (base_reader_->Done()) {
806 key_ = base_reader_->Key();
807 base_reader_->SwapHolder(&holder_);
811 producer_sem_.Signal();
817 KALDI_ASSERT(base_reader_ != NULL && thread_.joinable());
819 consumer_sem_.Wait();
822 ans = base_reader_->Close();
830 producer_sem_.Signal();
838 KALDI_ERR <<
"Error detected closing background reader " 839 <<
"(relates to ',bg' modifier)";
856 template<
class Holder>
858 &rspecifier): impl_(NULL) {
859 if (rspecifier !=
"" && !
Open(rspecifier))
860 KALDI_ERR <<
"Error constructing TableReader: rspecifier is " << rspecifier;
863 template<
class Holder>
867 KALDI_ERR <<
"Could not close previously open object.";
880 KALDI_WARN <<
"Invalid rspecifier " << rspecifier;
883 if (!
impl_->Open(rspecifier)) {
891 if (!
impl_->Open(
"")) {
900 template<
class Holder>
903 bool ans =
impl_->Close();
910 template<
class Holder>
912 return (
impl_ != NULL);
917 template<
class Holder>
925 template<
class Holder>
928 impl_->FreeCurrent();
932 template<
class Holder>
936 return impl_->Value();
941 template<
class Holder>
947 template<
class Holder>
950 return impl_->Done();
954 template<
class Holder>
964 typedef typename Holder::T
T;
966 virtual bool Open(
const std::string &wspecifier) = 0;
974 virtual bool Write(
const std::string &key,
const T &value) = 0;
978 virtual void Flush() = 0;
980 virtual bool Close() = 0;
982 virtual bool IsOpen()
const = 0;
995 template<
class Holder>
998 typedef typename Holder::T
T;
1000 virtual bool Open(
const std::string &wspecifier) {
1002 case kUninitialized:
1005 KALDI_ERR <<
"Opening stream, already open with write error.";
1006 case kOpen:
default:
1009 KALDI_ERR <<
"Opening stream, error closing previously open stream.";
1011 wspecifier_ = wspecifier;
1013 &archive_wxfilename_,
1018 if (output_.Open(archive_wxfilename_, opts_.binary,
false)) {
1025 state_ = kUninitialized;
1032 case kUninitialized:
return false;
1033 case kOpen:
case kWriteError:
return true;
1034 default:
KALDI_ERR <<
"IsOpen() called on TableWriter in invalid state.";
1041 virtual bool Write(
const std::string &key,
const T &value) {
1047 KALDI_WARN <<
"Attempting to write to invalid stream.";
1049 case kUninitialized:
default:
1050 KALDI_ERR <<
"Write called on invalid stream";
1054 KALDI_ERR <<
"Using invalid key " << key;
1055 output_.Stream() << key <<
' ';
1056 if (!Holder::Write(output_.Stream(), opts_.binary, value)) {
1059 state_ = kWriteError;
1062 if (state_ == kWriteError)
return false;
1075 case kWriteError:
case kOpen:
1076 output_.Stream().flush();
1079 KALDI_WARN <<
"Flush called on not-open writer.";
1084 if (!this->
IsOpen() || !output_.IsOpen())
1085 KALDI_ERR <<
"Close called on a stream that was not open." 1086 << this->
IsOpen() <<
", " << output_.IsOpen();
1087 bool close_success = output_.Close();
1088 if (!close_success) {
1089 KALDI_WARN <<
"Error closing stream: wspecifier is " << wspecifier_;
1090 state_ = kUninitialized;
1093 if (state_ == kWriteError) {
1094 KALDI_WARN <<
"Closing writer in error state: wspecifier is " 1096 state_ = kUninitialized;
1099 state_ = kUninitialized;
1109 KALDI_ERR <<
"At TableWriter destructor: Write failed or stream close " 1110 <<
"failed: wspecifier is "<< wspecifier_;
1135 template<
class Holder>
1138 typedef typename Holder::T
T;
1142 virtual bool Open(
const std::string &wspecifier) {
1145 KALDI_ERR <<
" Opening already open TableWriter: call Close first.";
1146 case kUninitialized:
case kNotReadScript:
1149 wspecifier_ = wspecifier;
1152 &script_rxfilename_,
1161 state_ = kNotReadScript;
1164 std::sort(script_.begin(), script_.end());
1165 for (
size_t i = 0;
i+1 < script_.size();
i++) {
1166 if (script_[
i].first.compare(script_[
i+1].first) >= 0) {
1169 <<
" contains duplicate key " << script_[
i].first;
1170 state_ = kNotReadScript;
1174 state_ = kReadScript;
1178 virtual bool IsOpen()
const {
return (state_ == kReadScript); }
1182 KALDI_ERR <<
"Close() called on TableWriter that was not open.";
1183 state_ = kUninitialized;
1191 virtual bool Write(
const std::string &key,
const T &value) {
1193 KALDI_ERR <<
"Write called on invalid stream";
1196 KALDI_ERR <<
"Using invalid key " << key;
1198 std::string wxfilename;
1199 if (!LookupFilename(key, &wxfilename)) {
1200 if (opts_.permissive) {
1206 <<
" has no entry for key " <<key;
1211 if (!output.
Open(wxfilename, opts_.binary,
false)) {
1219 if (!Holder::Write(output.
Stream(), opts_.binary, value)
1220 || !output.
Close()) {
1244 if (last_found_ < script_.size() && script_[last_found_].first == key) {
1245 *wxfilename = script_[last_found_].second;
1248 std::pair<std::string, std::string> pr(key,
"");
1251 typedef typename std::vector<std::pair<std::string, std::string> >
1252 ::const_iterator IterType;
1253 IterType iter = std::lower_bound(script_.begin(), script_.end(), pr);
1254 if (iter != script_.end() && iter->first == key) {
1255 last_found_ = iter - script_.begin();
1256 *wxfilename = iter->second;
1275 std::vector<std::pair<std::string, std::string> >
script_;
1288 template<
class Holder>
1291 typedef typename Holder::T
T;
1293 virtual bool Open(
const std::string &wspecifier) {
1295 case kUninitialized:
1298 KALDI_ERR <<
"Opening stream, already open with write error.";
1299 case kOpen:
default:
1302 KALDI_ERR <<
"Opening stream, error closing previously open stream.";
1304 wspecifier_ = wspecifier;
1306 &archive_wxfilename_,
1307 &script_wxfilename_,
1311 KALDI_WARN <<
"When writing to both archive and script, the script file " 1312 "will generally not be interpreted correctly unless the archive is " 1313 "an actual file: wspecifier = " << wspecifier;
1315 if (!archive_output_.Open(archive_wxfilename_, opts_.binary,
false)) {
1317 state_ = kUninitialized;
1320 if (!script_output_.Open(script_wxfilename_,
false,
false)) {
1323 archive_output_.Close();
1324 state_ = kUninitialized;
1333 case kUninitialized:
return false;
1334 case kOpen:
case kWriteError:
return true;
1335 default:
KALDI_ERR <<
"IsOpen() called on TableWriter in invalid state.";
1341 std::string *output)
const {
1342 std::ostringstream ss;
1343 ss <<
':' << streampos;
1345 *output = archive_wxfilename_ + ss.str();
1355 virtual bool Write(
const std::string &key,
const T &value) {
1361 KALDI_WARN <<
"Writing to non-open TableWriter object.";
1363 case kUninitialized:
default:
1364 KALDI_ERR <<
"Write called on invalid stream";
1368 KALDI_ERR <<
"Using invalid key " << key;
1369 std::ostream &archive_os = archive_output_.Stream();
1370 archive_os << key <<
' ';
1371 typename std::ostream::pos_type archive_os_pos = archive_os.tellp();
1374 std::string offset_rxfilename;
1376 MakeFilename(archive_os_pos, &offset_rxfilename);
1381 std::ostream &script_os = script_output_.Stream();
1382 script_output_.Stream() << key <<
' ' << offset_rxfilename <<
'\n';
1384 if (!Holder::Write(archive_output_.Stream(), opts_.binary, value)) {
1387 state_ = kWriteError;
1391 if (script_os.fail()) {
1392 KALDI_WARN <<
"Write failure to script file detected: " 1394 state_ = kWriteError;
1398 if (archive_os.fail()) {
1399 KALDI_WARN <<
"Write failure to archive file detected: " 1401 state_ = kWriteError;
1405 if (state_ == kWriteError)
return false;
1418 case kWriteError:
case kOpen:
1419 archive_output_.Stream().flush();
1420 script_output_.Stream().flush();
1423 KALDI_WARN <<
"Flush called on not-open writer.";
1429 KALDI_ERR <<
"Close called on a stream that was not open.";
1430 bool close_success =
true;
1431 if (archive_output_.IsOpen())
1432 if (!archive_output_.Close()) close_success =
false;
1433 if (script_output_.IsOpen())
1434 if (!script_output_.Close()) close_success =
false;
1435 bool ans = close_success && (state_ != kWriteError);
1436 state_ = kUninitialized;
1447 KALDI_ERR <<
"Write failed or stream close failed: " 1466 template<
class Holder>
1468 if (wspecifier !=
"" && !
Open(wspecifier))
1469 KALDI_ERR <<
"Failed to open table for writing with wspecifier: " << wspecifier
1470 <<
": errno (in case it's relevant) is: " << strerror(errno);
1473 template<
class Holder>
1475 return (
impl_ != NULL);
1479 template<
class Holder>
1483 KALDI_ERR <<
"Failed to close previously open writer.";
1498 KALDI_WARN <<
"ClassifyWspecifier: invalid wspecifier " << wspecifier;
1501 if (
impl_->Open(wspecifier)) {
1510 template<
class Holder>
1512 const T &value)
const {
1514 if (!
impl_->Write(key, value))
1515 KALDI_ERR <<
"Error in TableWriter::Write";
1520 template<
class Holder>
1526 template<
class Holder>
1529 bool ans =
impl_->Close();
1536 template<
class Holder>
1539 KALDI_ERR <<
"Error closing TableWriter [in destructor].";
1571 typedef typename Holder::T
T;
1573 virtual bool Open(
const std::string &rspecifier) = 0;
1575 virtual bool HasKey(
const std::string &key) = 0;
1577 virtual const T &Value(
const std::string &key) = 0;
1579 virtual bool Close() = 0;
1592 template<
class Holder>
1596 typedef typename Holder::T
T;
1600 virtual bool Open(
const std::string &rspecifier) {
1602 case kNotHaveObject:
case kHaveObject:
case kHaveRange:
1603 KALDI_ERR <<
" Opening already open RandomAccessTableReader:" 1604 " call Close first.";
1605 case kUninitialized:
case kNotReadScript:
1608 rspecifier_ = rspecifier;
1610 &script_rxfilename_,
1619 state_ = kNotReadScript;
1623 rspecifier_ = rspecifier;
1629 std::sort(script_.begin(), script_.end());
1630 for (
size_t i = 0;
i + 1 < script_.size();
i++) {
1631 if (script_[
i].first.compare(script_[
i+1].first) >= 0) {
1633 bool same = (script_[
i].first == script_[
i+1].first);
1635 << (same ?
" contains duplicate key: " :
1636 " is not sorted (remove s, option or add ns, option):" 1637 " key is ") << script_[
i].first;
1638 state_ = kNotReadScript;
1642 state_ = kNotHaveObject;
1648 return (state_ == kNotHaveObject || state_ == kHaveObject ||
1649 state_ == kHaveRange);
1654 KALDI_ERR <<
"Close() called on RandomAccessTableReader that was not" 1657 range_holder_.Clear();
1658 state_ = kUninitialized;
1663 data_rxfilename_ =
"";
1669 virtual bool HasKey(
const std::string &key) {
1670 bool preload = opts_.permissive;
1673 return HasKeyInternal(key, preload);
1679 virtual const T&
Value(
const std::string &key) {
1680 if (!HasKeyInternal(key,
true))
1681 KALDI_ERR <<
"Could not get item for key " << key
1682 <<
", rspecifier is " << rspecifier_ <<
" [to ignore this, " 1683 <<
"add the p, (permissive) option to the rspecifier.";
1685 if (state_ == kHaveObject) {
1686 return holder_.Value();
1689 return range_holder_.Value();
1705 case kUninitialized:
case kNotReadScript:
1706 KALDI_ERR <<
"HasKey called on RandomAccessTableReader object that is" 1709 if (key == key_ && range_.empty())
1716 case kNotHaveObject:
default:
break;
1720 if (!LookupKey(key, &key_pos)) {
1728 std::string data_rxfilename, range;
1731 if (script_[key_pos].second[script_[key_pos].second.size()-1] ==
']') {
1735 KALDI_ERR <<
"TableReader: failed to parse range in '" 1736 << script_[key_pos].second <<
"'";
1739 data_rxfilename = script_[key_pos].second;
1741 if (state_ == kHaveRange) {
1742 if (data_rxfilename_ == data_rxfilename && range_ == range) {
1748 range_holder_.Clear();
1749 state_ = kHaveObject;
1753 if (state_ == kHaveObject) {
1754 if (data_rxfilename_ != data_rxfilename) {
1756 state_ = kNotHaveObject;
1764 data_rxfilename_ = data_rxfilename;
1766 if (state_ == kNotHaveObject) {
1768 if (!input_.Open(data_rxfilename)) {
1773 if (holder_.Read(input_.Stream())) {
1774 state_ = kHaveObject;
1785 if (range_holder_.ExtractRange(holder_, range)) {
1786 state_ = kHaveRange;
1791 <<
"[" << range <<
"]";
1802 bool LookupKey(
const std::string &key,
size_t *script_offset) {
1807 if (last_found_ < script_.size() && script_[last_found_].first == key) {
1808 *script_offset = last_found_;
1812 if (last_found_ < script_.size() && script_[last_found_].first == key) {
1813 *script_offset = last_found_;
1816 std::pair<std::string, std::string> pr(key,
"");
1819 typedef typename std::vector<std::pair<std::string, std::string> >
1820 ::const_iterator IterType;
1821 IterType iter = std::lower_bound(script_.begin(), script_.end(), pr);
1822 if (iter != script_.end() && iter->first == key) {
1823 last_found_ = *script_offset = iter - script_.begin();
1860 std::vector<std::pair<std::string, std::string> >
script_;
1894 template<
class Holder>
1898 typedef typename Holder::T
T;
1901 state_(kUninitialized) { }
1903 virtual bool Open(
const std::string &rspecifier) {
1904 if (state_ != kUninitialized) {
1906 KALDI_ERR <<
"Error closing previous input.";
1908 rspecifier_ = rspecifier;
1915 if (Holder::IsReadInBinary())
1916 ans = input_.Open(archive_rxfilename_, NULL);
1918 ans = input_.OpenTextMode(archive_rxfilename_);
1922 state_ = kUninitialized;
1936 if (state_ != kNoObject)
1937 KALDI_ERR <<
"ReadNextObject() called from wrong state.";
1939 std::istream &is = input_.Stream();
1949 KALDI_WARN <<
"Error reading archive: rspecifier is " << rspecifier_;
1954 if ((c = is.peek()) !=
' ' && c !=
'\t' && c !=
'\n') {
1958 KALDI_WARN <<
"Invalid archive file format: expected space after key " 1960 <<
", got character " 1962 <<
", reading archive " 1967 if (c !=
'\n') is.get();
1968 holder_ =
new Holder;
1969 if (holder_->Read(is)) {
1970 state_ = kHaveObject;
1973 KALDI_WARN <<
"Object read failed, reading archive " 1984 case kEof:
case kError:
case kHaveObject:
case kNoObject:
return true;
1985 case kUninitialized:
return false;
1986 default:
KALDI_ERR <<
"IsOpen() called on invalid object.";
1995 KALDI_ERR <<
"Close() called on TableReader twice or otherwise wrongly.";
1996 if (input_.IsOpen())
1998 if (state_ == kHaveObject) {
2005 bool ans = (state_ != kError);
2006 state_ = kUninitialized;
2007 if (!ans && opts_.permissive) {
2008 KALDI_WARN <<
"Error state detected closing reader. " 2009 <<
"Ignoring it because you specified permissive mode.";
2017 KALDI_ASSERT(state_ == kUninitialized && holder_ == NULL);
2050 template<
class Holder>
2066 typedef typename Holder::T
T;
2073 return this->CloseInternal();
2076 virtual bool HasKey(
const std::string &key) {
2077 return FindKeyInternal(key);
2079 virtual const T &
Value(
const std::string &key) {
2080 if (!FindKeyInternal(key)) {
2081 KALDI_ERR <<
"Value() called but no such key " << key
2084 KALDI_ASSERT(this->state_ == kHaveObject && key == this->cur_key_
2085 && holder_ != NULL);
2086 return this->holder_->Value();
2094 KALDI_ERR <<
"Error closing RandomAccessTableReader: rspecifier is " 2104 if (!last_requested_key_.empty()) {
2105 if (key.compare(last_requested_key_) < 0) {
2106 KALDI_ERR <<
"You provided the \"cs\" option " 2107 <<
"but are not calling with keys in sorted order: " 2108 << key <<
" < " << last_requested_key_ <<
": rspecifier is " 2113 last_requested_key_ = key;
2115 if (state_ == kNoObject)
2121 if (state_ == kEof || state_ == kError)
return false;
2123 if (state_ == kUninitialized)
2124 KALDI_ERR <<
"Trying to access a RandomAccessTableReader object that is" 2127 std::string last_key_;
2131 int compare = key.compare(cur_key_);
2134 }
else if (compare < 0) {
2139 last_key_ = cur_key_;
2146 if (state_ != kHaveObject)
2148 if (cur_key_.compare(last_key_) <= 0) {
2149 KALDI_ERR <<
"You provided the \"s\" option " 2150 <<
" (sorted order), but keys are out of order or" 2152 << last_key_ <<
" is followed by " << cur_key_
2153 <<
": rspecifier is " << rspecifier_;
2166 template<
class Holder>
2183 typedef typename Holder::T
T;
2186 last_found_index_(static_cast<
size_t>(-1)),
2187 pending_delete_(static_cast<
size_t>(-1)) { }
2190 for (
size_t i = 0;
i < seen_pairs_.size();
i++)
2191 delete seen_pairs_[
i].second;
2192 seen_pairs_.clear();
2194 pending_delete_ =
static_cast<size_t>(-1);
2195 last_found_index_ =
static_cast<size_t>(-1);
2197 return this->CloseInternal();
2199 virtual bool HasKey(
const std::string &key) {
2200 HandlePendingDelete();
2202 bool ans = FindKeyInternal(key, &index);
2203 if (ans && opts_.once && seen_pairs_[index].second == NULL) {
2206 KALDI_ERR <<
"Error: HasKey called after Value() already called for " 2207 <<
" that key, and once (o) option specified: rspecifier is " 2212 virtual const T &
Value(
const std::string &key) {
2213 HandlePendingDelete();
2215 if (!FindKeyInternal(key, &index)) {
2216 KALDI_ERR <<
"Value() called but no such key " << key
2219 if (seen_pairs_[index].second == NULL) {
2220 KALDI_ERR <<
"Error: Value() called more than once for key " 2221 << key <<
" and once (o) option specified: rspecifier is " 2225 pending_delete_ = index;
2226 return seen_pairs_[index].second->Value();
2233 KALDI_ERR <<
"Error closing RandomAccessTableReader: rspecifier is " 2238 const size_t npos =
static_cast<size_t>(-1);
2239 if (pending_delete_ != npos) {
2241 KALDI_ASSERT(seen_pairs_[pending_delete_].second != NULL);
2242 delete seen_pairs_[pending_delete_].second;
2243 seen_pairs_[pending_delete_].second = NULL;
2244 pending_delete_ = npos;
2261 if (last_found_index_ < seen_pairs_.size()
2262 && seen_pairs_[last_found_index_].first == key) {
2263 *index = last_found_index_;
2267 if (state_ == kUninitialized)
2268 KALDI_ERR <<
"Trying to access a RandomAccessTableReader object that is" 2275 bool looped =
false;
2276 while (state_ == kNoObject &&
2277 (seen_pairs_.empty() || key.compare(seen_pairs_.back().first) > 0)) {
2285 if (state_ == kHaveObject) {
2286 if (!seen_pairs_.empty() &&
2287 cur_key_.compare(seen_pairs_.back().first) <= 0) {
2291 KALDI_ERR <<
"You provided the sorted (s) option but keys in archive " 2293 <<
"in sorted order: " << seen_pairs_.back().first
2294 <<
" is followed by " << cur_key_;
2297 seen_pairs_.push_back(std::make_pair(cur_key_, holder_));
2304 if (!seen_pairs_.empty() && seen_pairs_.back().first == key) {
2305 last_found_index_ = *index = seen_pairs_.size() - 1;
2312 std::pair<std::string, Holder*> pr(key, static_cast<Holder*>(NULL));
2313 typename std::vector<std::pair<std::string, Holder*> >::iterator
2314 iter = std::lower_bound(seen_pairs_.begin(), seen_pairs_.end(),
2316 if (iter != seen_pairs_.end() &&
2317 key == iter->first) {
2318 last_found_index_ = *index = (iter - seen_pairs_.begin());
2338 inline bool operator() (
const std::pair<std::string, Holder*> &pr1,
2339 const std::pair<std::string, Holder*> &pr2) {
2340 return (pr1.first.compare(pr2.first) < 0);
2357 template<
class Holder>
2373 typedef typename Holder::T
T;
2377 to_delete_iter_valid_(false) {
2378 map_.max_load_factor(0.5);
2383 for (
typename MapType::iterator iter = map_.begin();
2386 delete iter->second;
2389 first_deleted_string_ =
"";
2390 to_delete_iter_valid_ =
false;
2391 return this->CloseInternal();
2394 virtual bool HasKey(
const std::string &key) {
2395 HandlePendingDelete();
2396 return FindKeyInternal(key, NULL);
2398 virtual const T &
Value(
const std::string &key) {
2399 HandlePendingDelete();
2400 const T *ans_ptr = NULL;
2401 if (!FindKeyInternal(key, &ans_ptr))
2402 KALDI_ERR <<
"Value() called but no such key " << key
2411 KALDI_ERR <<
"Error closing RandomAccessTableReader: rspecifier is " 2416 if (to_delete_iter_valid_) {
2417 to_delete_iter_valid_ =
false;
2418 delete to_delete_iter_->second;
2419 if (first_deleted_string_.length() == 0)
2420 first_deleted_string_ = to_delete_iter_->first;
2421 map_.erase(to_delete_iter_);
2436 typename MapType::iterator iter = map_.find(key);
2437 if (iter != map_.end()) {
2438 if (value_ptr == NULL) {
2441 *value_ptr = &(iter->second->Value());
2444 to_delete_iter_ = iter;
2446 to_delete_iter_valid_ =
true;
2451 while (state_ == kNoObject) {
2453 if (state_ == kHaveObject) {
2457 std::pair<typename MapType::iterator, bool> pr =
2458 map_.insert(
typename MapType::value_type(cur_key_, holder_));
2463 KALDI_ERR <<
"Error in RandomAccessTableReader: duplicate key " 2464 << cur_key_ <<
" in archive " << archive_rxfilename_;
2467 if (cur_key_ == key) {
2468 if (value_ptr == NULL) {
2471 *value_ptr = &(pr.first->second->Value());
2474 to_delete_iter_ = pr.first;
2476 to_delete_iter_valid_ =
true;
2483 if (opts_.once && key == first_deleted_string_) {
2484 KALDI_ERR <<
"You specified the once (o) option but " 2485 <<
"you are calling using key " << key
2486 <<
" more than once: rspecifier is " << rspecifier_;
2492 typedef unordered_map<std::string, Holder*, StringHasher>
MapType;
2507 template<
class Holder>
2509 std::string &rspecifier):
2511 if (rspecifier !=
"" && !Open(rspecifier))
2512 KALDI_ERR <<
"Error opening RandomAccessTableReader object " 2513 " (rspecifier is: " << rspecifier <<
")";
2516 template<
class Holder>
2541 if (!impl_->Open(rspecifier)) {
2550 template<
class Holder>
2554 KALDI_ERR <<
"Invalid key \"" << key <<
'"';
2555 return impl_->HasKey(key);
2559 template<
class Holder>
2563 return impl_->Value(key);
2566 template<
class Holder>
2569 bool ans =impl_->Close();
2575 template<
class Holder>
2577 if (IsOpen() && !Close())
2578 KALDI_ERR <<
"failure detected in destructor.";
2581 template<
class Holder>
2584 KALDI_ERR <<
"Trying to use empty SequentialTableReader (perhaps you " 2585 <<
"passed the empty string as an argument to a program?)";
2589 template<
class Holder>
2592 KALDI_ERR <<
"Trying to use empty RandomAccessTableReader (perhaps you " 2593 <<
"passed the empty string as an argument to a program?)";
2597 template<
class Holder>
2600 KALDI_ERR <<
"Trying to use empty TableWriter (perhaps you " 2601 <<
"passed the empty string as an argument to a program?)";
2605 template<
class Holder>
2607 const std::string &table_rxfilename,
2608 const std::string &utt2spk_rxfilename):
2609 reader_(table_rxfilename), token_reader_(table_rxfilename.empty() ?
"" :
2610 utt2spk_rxfilename),
2611 utt2spk_rxfilename_(utt2spk_rxfilename) { }
2613 template<
class Holder>
2615 const std::string &table_rxfilename,
2616 const std::string &utt2spk_rxfilename) {
2620 if (!
reader_.Open(table_rxfilename))
return false;
2622 if (!utt2spk_rxfilename.empty()) {
2632 template<
class Holder>
2639 KALDI_ERR <<
"Attempting to read key " << utt <<
", which is not present " 2640 <<
"in utt2spk map or similar map being read from " 2649 template<
class Holder>
2651 const std::string &utt) {
2654 KALDI_ERR <<
"Attempting to read key " << utt <<
", which is not present " 2655 <<
"in utt2spk map or similar map being read from " 2672 #endif // KALDI_UTIL_KALDI_TABLE_INL_H_
virtual ~RandomAccessTableReaderSortedArchiveImpl()
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
virtual bool Open(const std::string &rspecifier)
virtual bool Open(const std::string &rspecifier)
bool FindKeyInternal(const std::string &key)
MapType::iterator to_delete_iter_
bool to_delete_iter_valid_
virtual bool IsOpen() const
virtual void FreeCurrent()
virtual bool IsOpen() const
virtual ~TableWriterBothImpl()
virtual bool Open(const std::string &wspecifier)
bool Open(const std::string &wspecifier)
std::string archive_wxfilename_
SequentialTableReaderImplBase< Holder > * base_reader_
virtual const T & Value(const std::string &key)
virtual bool HasKeyInternal(const std::string &key, bool preload)
~SequentialTableReaderBackgroundImpl()
std::string utt2spk_rxfilename_
RandomAccessTableReader< TokenHolder > token_reader_
virtual bool Open(const std::string &rxfilename)
This class is for when you are reading something in random access, but it may actually be stored per-...
static void run(SequentialTableReaderBackgroundImpl< Holder > *object)
virtual void SwapHolder(Holder *other_holder)=0
bool Open(const std::string &rspecifier)
void HandlePendingDelete()
SequentialTableReaderScriptImpl()
SequentialTableReaderArchiveImpl()
virtual bool IsOpen() const
bool LookupFilename(const std::string &key, std::string *wxfilename)
virtual bool Open(const std::string &wspecifier)
A templated class for writing objects to an archive or script file; see The Table concept...
void SwapHolder(Holder *other_holder)
SequentialTableReaderImplBase< Holder > * impl_
virtual ~TableWriterImplBase()
#define KALDI_DISALLOW_COPY_AND_ASSIGN(type)
std::string first_deleted_string_
virtual bool Done() const
virtual bool HasKey(const std::string &key)
virtual std::string Key()
void Write(const std::string &key, const T &value) const
std::vector< std::pair< std::string, std::string > > script_
virtual ~SequentialTableReaderImplBase()
void MakeFilename(typename std::ostream::pos_type streampos, std::string *output) const
RspecifierType ClassifyRspecifier(const std::string &rspecifier, std::string *rxfilename, RspecifierOptions *opts)
bool IsToken(const std::string &token)
Returns true if "token" is nonempty, and all characters are printable and whitespace-free.
std::vector< std::pair< std::string, std::string > > script_
std::vector< std::pair< std::string, Holder * > > seen_pairs_
Allows random access to a collection of objects in an archive or script file; see The Table concept...
std::string archive_wxfilename_
unordered_map< std::string, Holder *, StringHasher > MapType
virtual ~RandomAccessTableReaderScriptImpl()
bool FindKeyInternal(const std::string &key, const T **value_ptr=NULL)
virtual ~SequentialTableReaderScriptImpl()
virtual ~TableWriterScriptImpl()
virtual ~RandomAccessTableReaderImplBase()
virtual bool Open(const std::string &rxfilename)=0
virtual bool Open(const std::string &rspecifier)
virtual ~RandomAccessTableReaderUnsortedArchiveImpl()
RandomAccessTableReaderDSortedArchiveImpl()
RandomAccessTableReader()
bool EnsureObjectLoaded()
virtual const T & Value(const std::string &key)
virtual bool Write(const std::string &key, const T &value)
virtual bool IsOpen() const
virtual ~RandomAccessTableReaderDSortedArchiveImpl()
void SplitStringOnFirstSpace(const std::string &str, std::string *first, std::string *rest)
Removes leading and trailing white space from the string, then splits on the first section of whitesp...
bool Open(const std::string &table_rxfilename, const std::string &utt2spk_rxfilename)
Note: when calling Open, utt2spk_rxfilename may be empty.
std::string data_rxfilename_
RandomAccessTableReaderUnsortedArchiveImpl()
virtual ~TableWriterArchiveImpl()
RandomAccessTableReaderSortedArchiveImpl()
RandomAccessTableReaderScriptImpl()
std::string script_rxfilename_
std::string script_rxfilename_
virtual bool Write(const std::string &key, const T &value)
virtual bool Write(const std::string &key, const T &value)
virtual bool Done() const
A templated class for reading objects sequentially from an archive or script file; see The Table conc...
std::string archive_rxfilename_
virtual const T & Value(const std::string &key)
virtual const T & Value(const std::string &key)
virtual std::string Key()
virtual bool Done() const =0
virtual bool IsOpen() const
virtual void FreeCurrent()
bool HasKey(const std::string &key)
virtual bool IsOpen() const
virtual bool Open(const std::string &rspecifier)
KALDI_DISALLOW_COPY_AND_ASSIGN(SequentialTableReaderImplBase)
RandomAccessTableReader< Holder > reader_
WspecifierType ClassifyWspecifier(const std::string &wspecifier, std::string *archive_wxfilename, std::string *script_wxfilename, WspecifierOptions *opts)
std::string CharToString(const char &c)
virtual bool IsOpen() const =0
bool Open(const std::string &wxfilename, bool binary, bool write_header)
This opens the stream, with the given mode (binary or text).
bool ReadScriptFile(const std::string &rxfilename, bool warn, std::vector< std::pair< std::string, std::string > > *script_out)
virtual bool HasKey(const std::string &key)
std::string archive_rxfilename_
#define KALDI_ASSERT(cond)
std::string data_rxfilename_
std::string script_wxfilename_
virtual bool IsOpen() const
RandomAccessTableReaderArchiveImplBase()
virtual bool IsOpen() const
SequentialTableReaderImplBase()
std::string last_requested_key_
Last string provided to HasKey() or Value();.
OutputType ClassifyWxfilename(const std::string &filename)
ClassifyWxfilename interprets filenames as follows:
std::string PrintableRxfilename(const std::string &rxfilename)
PrintableRxfilename turns the rxfilename into a more human-readable form for error reporting...
std::string PrintableWxfilename(const std::string &wxfilename)
PrintableWxfilename turns the wxfilename into a more human-readable form for error reporting...
std::string script_rxfilename_
void SwapHolder(Holder *other_holder)
bool ExtractRangeSpecifier(const std::string &rxfilename_with_range, std::string *data_rxfilename, std::string *range)
const T & Value(const std::string &key)
bool FindKeyInternal(const std::string &key, size_t *index)
~RandomAccessTableReaderArchiveImplBase()
virtual bool Done() const
TableWriterImplBase< Holder > * impl_
virtual bool Open(const std::string &wspecifier)
void SwapHolder(Holder *other_holder)
bool LookupKey(const std::string &key, size_t *script_offset)
virtual std::string Key()=0
virtual void FreeCurrent()=0
SequentialTableReaderBackgroundImpl(SequentialTableReaderImplBase< Holder > *base_reader)
virtual ~SequentialTableReaderArchiveImpl()
virtual bool HasKey(const std::string &key)
virtual bool HasKey(const std::string &key)
void HandlePendingDelete()
virtual std::string Key()