Switch to unified view

a/src/utils/circache.cpp b/src/utils/circache.cpp
...
...
154
public:
154
public:
155
    int m_fd;
155
    int m_fd;
156
    ////// These are cache persistent state and written to the first block:
156
    ////// These are cache persistent state and written to the first block:
157
    // Maximum file size, after which we begin reusing old space
157
    // Maximum file size, after which we begin reusing old space
158
    off_t m_maxsize; 
158
    off_t m_maxsize; 
159
    // Offset of the oldest header. 
159
    // Offset of the oldest header, or max file offset (file size)
160
    // while the file is growing. This is the next write position.
160
    off_t m_oheadoffs;
161
    off_t m_oheadoffs;
161
    // Offset of last write (newest header)
162
    // Offset of last write (newest header)
162
    off_t m_nheadoffs;
163
    off_t m_nheadoffs;
163
    // Pad size for newest entry. 
164
    // Pad size for newest entry. 
164
    int   m_npadsize;
165
    int   m_npadsize;
...
...
186
    bool khEnter(const string& udi, off_t ofs)
187
    bool khEnter(const string& udi, off_t ofs)
187
    {
188
    {
188
        UdiH h(udi);
189
        UdiH h(udi);
189
190
190
        LOGDEB2(("Circache::khEnter: h %s offs %lu udi [%s]\n", 
191
        LOGDEB2(("Circache::khEnter: h %s offs %lu udi [%s]\n", 
191
         h.asHexString().c_str(), (ULONG)ofs, udi.c_str()));
192
              h.asHexString().c_str(), (ULONG)ofs, udi.c_str()));
192
193
193
        pair<kh_type::iterator, kh_type::iterator> p = m_ofskh.equal_range(h);
194
        pair<kh_type::iterator, kh_type::iterator> p = m_ofskh.equal_range(h);
194
195
195
        if (p.first != m_ofskh.end() && p.first->first == h) {
196
        if (p.first != m_ofskh.end() && p.first->first == h) {
196
            for (kh_type::iterator it = p.first; it != p.second; it++) {
197
            for (kh_type::iterator it = p.first; it != p.second; it++) {
197
                LOGDEB2(("Circache::khEnter: col h %s, ofs %lu\n", 
198
                LOGDEB2(("Circache::khEnter: col h %s, ofs %lu\n", 
198
             it->first.asHexString().c_str(),
199
                      it->first.asHexString().c_str(),
199
             (ULONG)it->second));
200
                      (ULONG)it->second));
200
                if (it->second == ofs) {
201
                if (it->second == ofs) {
201
                    // (h,offs) already there. Happens
202
                    // (h,offs) already there. Happens
202
                    LOGDEB2(("Circache::khEnter: already there\n"));
203
                    LOGDEB2(("Circache::khEnter: already there\n"));
203
                    return true;
204
                    return true;
204
                }
205
                }
...
...
225
        ofss.clear();
226
        ofss.clear();
226
227
227
        UdiH h(udi);
228
        UdiH h(udi);
228
229
229
        LOGDEB2(("Circache::khFind: h %s udi [%s]\n", 
230
        LOGDEB2(("Circache::khFind: h %s udi [%s]\n", 
230
         h.asHexString().c_str(), udi.c_str()));
231
              h.asHexString().c_str(), udi.c_str()));
231
232
232
        pair<kh_type::iterator, kh_type::iterator> p = m_ofskh.equal_range(h);
233
        pair<kh_type::iterator, kh_type::iterator> p = m_ofskh.equal_range(h);
233
234
234
#if 0
235
#if 0
235
        if (p.first == m_ofskh.end()) LOGDEB(("KHFIND: FIRST END()\n"));
236
        if (p.first == m_ofskh.end()) LOGDEB(("KHFIND: FIRST END()\n"));
...
...
316
        return  path_cat(d, "circache.crch");
317
        return  path_cat(d, "circache.crch");
317
    }
318
    }
318
319
319
    bool writefirstblock()
320
    bool writefirstblock()
320
    {
321
    {
321
    if (m_fd < 0) {
322
     if (m_fd < 0) {
322
        m_reason << "writefirstblock: not open ";
323
          m_reason << "writefirstblock: not open ";
323
        return false;
324
          return false;
324
    }
325
     }
325
326
326
        ostringstream s;
327
        ostringstream s;
327
        s << 
328
        s << 
328
            "maxsize = " << m_maxsize << "\n" <<
329
            "maxsize = " << m_maxsize << "\n" <<
329
            "oheadoffs = " << m_oheadoffs << "\n" <<
330
            "oheadoffs = " << m_oheadoffs << "\n" <<
...
...
345
        return true;
346
        return true;
346
    }
347
    }
347
348
348
    bool readfirstblock()
349
    bool readfirstblock()
349
    {
350
    {
350
    if (m_fd < 0) {
351
     if (m_fd < 0) {
351
        m_reason << "readfirstblock: not open ";
352
          m_reason << "readfirstblock: not open ";
352
        return false;
353
          return false;
353
    }
354
     }
354
355
355
        char bf[CIRCACHE_FIRSTBLOCK_SIZE];
356
        char bf[CIRCACHE_FIRSTBLOCK_SIZE];
356
357
357
        lseek(m_fd, 0, 0);
358
        lseek(m_fd, 0, 0);
358
        if (read(m_fd, bf, CIRCACHE_FIRSTBLOCK_SIZE) != 
359
        if (read(m_fd, bf, CIRCACHE_FIRSTBLOCK_SIZE) != 
...
...
391
        return true;
392
        return true;
392
    }            
393
    }            
393
394
394
    bool writeEntryHeader(off_t offset, const EntryHeaderData& d)
395
    bool writeEntryHeader(off_t offset, const EntryHeaderData& d)
395
    {
396
    {
396
    if (m_fd < 0) {
397
     if (m_fd < 0) {
397
        m_reason << "writeEntryHeader: not open ";
398
          m_reason << "writeEntryHeader: not open ";
398
        return false;
399
          return false;
399
    }
400
     }
400
        char bf[CIRCACHE_HEADER_SIZE];
401
        char bf[CIRCACHE_HEADER_SIZE];
401
        memset(bf, 0, CIRCACHE_HEADER_SIZE);
402
        memset(bf, 0, CIRCACHE_HEADER_SIZE);
402
        snprintf(bf, CIRCACHE_HEADER_SIZE, 
403
        snprintf(bf, CIRCACHE_HEADER_SIZE, 
403
         headerformat, d.dicsize, d.datasize, d.padsize, d.flags);
404
              headerformat, d.dicsize, d.datasize, d.padsize, d.flags);
404
        if (lseek(m_fd, offset, 0) != offset) {
405
        if (lseek(m_fd, offset, 0) != offset) {
405
            m_reason << "CirCache::weh: lseek(" << offset << 
406
            m_reason << "CirCache::weh: lseek(" << offset << 
406
                ") failed: errno " << errno;
407
                ") failed: errno " << errno;
407
            return false;
408
            return false;
408
        }
409
        }
...
...
413
        return true;
414
        return true;
414
    }
415
    }
415
416
416
    CCScanHook::status readEntryHeader(off_t offset, EntryHeaderData& d)
417
    CCScanHook::status readEntryHeader(off_t offset, EntryHeaderData& d)
417
    {
418
    {
418
    if (m_fd < 0) {
419
     if (m_fd < 0) {
419
        m_reason << "readEntryHeader: not open ";
420
          m_reason << "readEntryHeader: not open ";
420
            return CCScanHook::Error;
421
            return CCScanHook::Error;
421
    }
422
     }
422
423
423
        if (lseek(m_fd, offset, 0) != offset) {
424
        if (lseek(m_fd, offset, 0) != offset) {
424
            m_reason << "readEntryHeader: lseek(" << offset << 
425
            m_reason << "readEntryHeader: lseek(" << offset << 
425
                ") failed: errno " << errno;
426
                ") failed: errno " << errno;
426
            return CCScanHook::Error;
427
            return CCScanHook::Error;
...
...
449
    }
450
    }
450
451
451
    CCScanHook::status scan(off_t startoffset, CCScanHook *user, 
452
    CCScanHook::status scan(off_t startoffset, CCScanHook *user, 
452
                            bool fold = false)
453
                            bool fold = false)
453
    {
454
    {
454
    if (m_fd < 0) {
455
     if (m_fd < 0) {
455
        m_reason << "scan: not open ";
456
          m_reason << "scan: not open ";
456
            return CCScanHook::Error;
457
            return CCScanHook::Error;
457
    }
458
     }
458
459
459
        off_t so0 = startoffset;
460
        off_t so0 = startoffset;
460
        bool already_folded = false;
461
        bool already_folded = false;
461
        
462
        
462
        while (true) {
463
        while (true) {
...
...
620
class CCScanHookRecord : public  CCScanHook {
621
class CCScanHookRecord : public  CCScanHook {
621
public:
622
public:
622
    off_t headoffs;
623
    off_t headoffs;
623
    off_t padsize;
624
    off_t padsize;
624
    CCScanHookRecord()
625
    CCScanHookRecord()
625
    : headoffs(0), padsize(0)
626
     : headoffs(0), padsize(0)
626
    {
627
    {
627
    }
628
    }
628
    virtual status takeone(off_t offs, const string& udi, 
629
    virtual status takeone(off_t offs, const string& udi, 
629
               const EntryHeaderData& d)
630
                        const EntryHeaderData& d)
630
    {
631
    {
631
    headoffs = offs;
632
     headoffs = offs;
632
    padsize = d.padsize;
633
     padsize = d.padsize;
633
    LOGDEB2(("CCScanHookRecord::takeone: offs %lld padsize %lld\n", 
634
     LOGDEB2(("CCScanHookRecord::takeone: offs %lld padsize %lld\n", 
634
         headoffs, padsize));
635
              headoffs, padsize));
635
        return Continue;
636
        return Continue;
636
    }
637
    }
637
};
638
};
638
639
639
string CirCache::getpath()
640
string CirCache::getpath()
...
...
642
}
643
}
643
644
644
bool CirCache::create(off_t maxsize, int flags)
645
bool CirCache::create(off_t maxsize, int flags)
645
{
646
{
646
    LOGDEB(("CirCache::create: [%s] maxsz %lld flags 0x%x\n", 
647
    LOGDEB(("CirCache::create: [%s] maxsz %lld flags 0x%x\n", 
647
        m_dir.c_str(), maxsize, flags));
648
          m_dir.c_str(), maxsize, flags));
648
    if (m_d == 0) {
649
    if (m_d == 0) {
649
    LOGERR(("CirCache::create: null data\n"));
650
     LOGERR(("CirCache::create: null data\n"));
650
    return false;
651
     return false;
651
    }
652
    }
652
653
653
    struct stat st;
654
    struct stat st;
654
    if (stat(m_dir.c_str(), &st) < 0) {
655
    if (stat(m_dir.c_str(), &st) < 0) {
655
    // Directory does not exist, create it
656
     // Directory does not exist, create it
656
    if (mkdir(m_dir.c_str(), 0777) < 0) {
657
     if (mkdir(m_dir.c_str(), 0777) < 0) {
657
        m_d->m_reason << "CirCache::create: mkdir(" << m_dir << 
658
          m_d->m_reason << "CirCache::create: mkdir(" << m_dir << 
658
        ") failed" << " errno " << errno;
659
             ") failed" << " errno " << errno;
659
        return false;
660
          return false;
660
    }
661
     }
661
    } else {
662
    } else {
662
    // If the file exists too, and truncate is not set, switch
663
     // If the file exists too, and truncate is not set, switch
663
    // to open-mode. Still may need to update header params.
664
     // to open-mode. Still may need to update header params.
664
    if (access(m_d->datafn(m_dir).c_str(), 0) >= 0 &&
665
     if (access(m_d->datafn(m_dir).c_str(), 0) >= 0 &&
665
        !(flags & CC_CRTRUNCATE)) {
666
          !(flags & CC_CRTRUNCATE)) {
666
        if (!open(CC_OPWRITE)) {
667
          if (!open(CC_OPWRITE)) {
667
        return false;
668
             return false;
668
      }
669
          }
669
        if (maxsize == m_d->m_maxsize &&
670
          if (maxsize == m_d->m_maxsize &&
670
        ((flags & CC_CRUNIQUE) != 0) == m_d->m_uniquentries) {
671
             ((flags & CC_CRUNIQUE) != 0) == m_d->m_uniquentries) {
671
        LOGDEB(("Header unchanged, no rewrite\n"));
672
             LOGDEB(("Header unchanged, no rewrite\n"));
672
        return true;
673
             return true;
673
      }
674
          }
674
        // If the new maxsize is bigger than current size, we need
675
          // If the new maxsize is bigger than current size, we need
675
        // to stop recycling if this is what we are doing.
676
          // to stop recycling if this is what we are doing.
676
        if (maxsize > m_d->m_maxsize && maxsize > st.st_size) {
677
          if (maxsize > m_d->m_maxsize && maxsize > st.st_size) {
677
        // Scan the file to find the last physical record. The
678
             // Scan the file to find the last physical record. The
678
        // ohead is set at physical eof, and nhead is the last
679
             // ohead is set at physical eof, and nhead is the last
679
        // scanned record
680
             // scanned record
680
        CCScanHookRecord rec;
681
             CCScanHookRecord rec;
681
        m_d->scan(CIRCACHE_FIRSTBLOCK_SIZE, &rec, false);
682
             m_d->scan(CIRCACHE_FIRSTBLOCK_SIZE, &rec, false);
682
        m_d->m_oheadoffs = lseek(m_d->m_fd, 0, SEEK_END);
683
             m_d->m_oheadoffs = lseek(m_d->m_fd, 0, SEEK_END);
683
        m_d->m_nheadoffs = rec.headoffs;
684
             m_d->m_nheadoffs = rec.headoffs;
684
        m_d->m_npadsize = rec.padsize;
685
             m_d->m_npadsize = rec.padsize;
685
      }
686
          }
686
        m_d->m_maxsize = maxsize;
687
          m_d->m_maxsize = maxsize;
687
        m_d->m_uniquentries = ((flags & CC_CRUNIQUE) != 0);
688
          m_d->m_uniquentries = ((flags & CC_CRUNIQUE) != 0);
688
        LOGDEB(("CirCache::create: rewriting header with "
689
          LOGDEB(("CirCache::create: rewriting header with "
689
            "maxsize %lld oheadoffs %lld nheadoffs %lld "
690
                  "maxsize %lld oheadoffs %lld nheadoffs %lld "
690
            "npadsize %d unient %d\n",
691
                  "npadsize %d unient %d\n",
691
            m_d->m_maxsize, m_d->m_oheadoffs, m_d->m_nheadoffs,
692
                  m_d->m_maxsize, m_d->m_oheadoffs, m_d->m_nheadoffs,
692
            m_d->m_npadsize, int(m_d->m_uniquentries)));
693
                  m_d->m_npadsize, int(m_d->m_uniquentries)));
693
        return m_d->writefirstblock();
694
          return m_d->writefirstblock();
694
    }
695
     }
695
    // Else fallthrough to create file
696
     // Else fallthrough to create file
696
    }
697
    }
697
698
698
    if ((m_d->m_fd = ::open(m_d->datafn(m_dir).c_str(), 
699
    if ((m_d->m_fd = ::open(m_d->datafn(m_dir).c_str(), 
699
                O_CREAT | O_RDWR | O_TRUNC, 0666)) < 0) {
700
                          O_CREAT | O_RDWR | O_TRUNC, 0666)) < 0) {
700
        m_d->m_reason << "CirCache::create: open/creat(" << 
701
        m_d->m_reason << "CirCache::create: open/creat(" << 
701
            m_d->datafn(m_dir) << ") failed " << "errno " << errno;
702
            m_d->datafn(m_dir) << ") failed " << "errno " << errno;
702
    return false;
703
     return false;
703
    }
704
    }
704
705
705
    m_d->m_maxsize = maxsize;
706
    m_d->m_maxsize = maxsize;
706
    m_d->m_oheadoffs = CIRCACHE_FIRSTBLOCK_SIZE;
707
    m_d->m_oheadoffs = CIRCACHE_FIRSTBLOCK_SIZE;
707
    m_d->m_uniquentries = ((flags & CC_CRUNIQUE) != 0);
708
    m_d->m_uniquentries = ((flags & CC_CRUNIQUE) != 0);
...
...
718
}
719
}
719
720
720
bool CirCache::open(OpMode mode)
721
bool CirCache::open(OpMode mode)
721
{
722
{
722
    if (m_d == 0) {
723
    if (m_d == 0) {
723
    LOGERR(("CirCache::open: null data\n"));
724
     LOGERR(("CirCache::open: null data\n"));
724
    return false;
725
     return false;
725
    }
726
    }
726
727
727
    if (m_d->m_fd >= 0)
728
    if (m_d->m_fd >= 0)
728
        ::close(m_d->m_fd);
729
        ::close(m_d->m_fd);
729
730
730
    if ((m_d->m_fd = ::open(m_d->datafn(m_dir).c_str(), 
731
    if ((m_d->m_fd = ::open(m_d->datafn(m_dir).c_str(), 
731
                mode == CC_OPREAD ? O_RDONLY : O_RDWR)) < 0) {
732
                          mode == CC_OPREAD ? O_RDONLY : O_RDWR)) < 0) {
732
        m_d->m_reason << "CirCache::open: open(" << m_d->datafn(m_dir) << 
733
        m_d->m_reason << "CirCache::open: open(" << m_d->datafn(m_dir) << 
733
            ") failed " << "errno " << errno;
734
            ") failed " << "errno " << errno;
734
        return false;
735
        return false;
735
    }
736
    }
736
    return m_d->readfirstblock();
737
    return m_d->readfirstblock();
...
...
935
public:
936
public:
936
    UINT sizewanted;
937
    UINT sizewanted;
937
    UINT sizeseen;
938
    UINT sizeseen;
938
    vector<pair<string, off_t> > squashed_udis;
939
    vector<pair<string, off_t> > squashed_udis;
939
    CCScanHookSpacer(int sz)
940
    CCScanHookSpacer(int sz)
940
    : sizewanted(sz), sizeseen(0) {assert(sz > 0);}
941
      : sizewanted(sz), sizeseen(0) {assert(sz > 0);}
941
942
942
    virtual status takeone(off_t offs, const string& udi, 
943
    virtual status takeone(off_t offs, const string& udi, 
943
                           const EntryHeaderData& d)
944
                           const EntryHeaderData& d)
944
    {
945
    {
945
        LOGDEB2(("Circache:ScanSpacer:off %u dcsz %u dtsz %u pdsz %u udi[%s]\n",
946
        LOGDEB2(("Circache:ScanSpacer:off %u dcsz %u dtsz %u pdsz %u udi[%s]\n",
946
         (UINT)offs, d.dicsize, d.datasize, d.padsize, udi.c_str()));
947
              (UINT)offs, d.dicsize, d.datasize, d.padsize, udi.c_str()));
947
        sizeseen += CIRCACHE_HEADER_SIZE + d.dicsize + d.datasize + d.padsize;
948
        sizeseen += CIRCACHE_HEADER_SIZE + d.dicsize + d.datasize + d.padsize;
948
        squashed_udis.push_back(make_pair(udi, offs));
949
        squashed_udis.push_back(make_pair(udi, offs));
949
        if (sizeseen >= sizewanted)
950
        if (sizeseen >= sizewanted)
950
            return Stop;
951
            return Stop;
951
        return Continue;
952
        return Continue;
...
...
1027
        // zero pad size
1028
        // zero pad size
1028
        EntryHeaderData pd;
1029
        EntryHeaderData pd;
1029
        if (m_d->readEntryHeader(m_d->m_nheadoffs, pd) != CCScanHook::Continue){
1030
        if (m_d->readEntryHeader(m_d->m_nheadoffs, pd) != CCScanHook::Continue){
1030
            return false;
1031
            return false;
1031
        }
1032
        }
1032
    if (int(pd.padsize) != m_d->m_npadsize) {
1033
     if (int(pd.padsize) != m_d->m_npadsize) {
1033
        m_d->m_reason << "CirCache::put: logic error: bad padsize ";
1034
          m_d->m_reason << "CirCache::put: logic error: bad padsize ";
1034
        return false;
1035
          return false;
1035
    }
1036
     }
1036
        if (pd.dicsize == 0) {
1037
        if (pd.dicsize == 0) {
1037
            // erased entry. Also recover the header space, no need to rewrite
1038
            // erased entry. Also recover the header space, no need to rewrite
1038
            // the header, we're going to write on it.
1039
            // the header, we're going to write on it.
1039
            recovpadsize += CIRCACHE_HEADER_SIZE;
1040
            recovpadsize += CIRCACHE_HEADER_SIZE;
1040
        } else {
1041
        } else {
...
...
1090
    }
1091
    }
1091
1092
1092
    char head[CIRCACHE_HEADER_SIZE];
1093
    char head[CIRCACHE_HEADER_SIZE];
1093
    memset(head, 0, CIRCACHE_HEADER_SIZE);
1094
    memset(head, 0, CIRCACHE_HEADER_SIZE);
1094
    snprintf(head, CIRCACHE_HEADER_SIZE, 
1095
    snprintf(head, CIRCACHE_HEADER_SIZE, 
1095
         headerformat, dic.size(), datalen, npadsize, flags);
1096
           headerformat, dic.size(), datalen, npadsize, flags);
1096
    struct iovec vecs[3];
1097
    struct iovec vecs[3];
1097
    vecs[0].iov_base = head;
1098
    vecs[0].iov_base = head;
1098
    vecs[0].iov_len = CIRCACHE_HEADER_SIZE;
1099
    vecs[0].iov_len = CIRCACHE_HEADER_SIZE;
1099
    vecs[1].iov_base = (void *)dic.c_str();
1100
    vecs[1].iov_base = (void *)dic.c_str();
1100
    vecs[1].iov_len = dic.size();
1101
    vecs[1].iov_len = dic.size();
...
...
1130
        return false;
1131
        return false;
1131
    }
1132
    }
1132
1133
1133
    eof = false;
1134
    eof = false;
1134
1135
1135
    // Read oldest header
1136
  off_t fsize = lseek(m_d->m_fd, 0, SEEK_END);
1137
  if (fsize == (off_t)-1) {
1138
      LOGERR(("CirCache::rewind: seek to EOF failed\n"));
1139
      return false;
1140
  }
1141
    // Read oldest header. This is either at the position pointed to
1142
    // by oheadoffs, or after the first block if the file is still
1143
    // growing.
1144
  if (m_d->m_oheadoffs == fsize) {
1145
      m_d->m_itoffs = CIRCACHE_FIRSTBLOCK_SIZE;
1146
  } else {
1136
    m_d->m_itoffs = m_d->m_oheadoffs;
1147
      m_d->m_itoffs = m_d->m_oheadoffs;
1148
  }
1137
    CCScanHook::status st = m_d->readEntryHeader(m_d->m_itoffs, m_d->m_ithd);
1149
    CCScanHook::status st = m_d->readEntryHeader(m_d->m_itoffs, m_d->m_ithd);
1138
1150
1139
    switch(st) {
1151
    switch(st) {
1140
    case CCScanHook::Eof:
1152
    case CCScanHook::Eof:
1141
        eof = true;
1153
        eof = true;
...
...
1260
        LOGDEB2(("InflateToDynBuf: avail_in %d total_in %d avail_out %d "
1272
        LOGDEB2(("InflateToDynBuf: avail_in %d total_in %d avail_out %d "
1261
                 "total_out %d\n", d_stream.avail_in, d_stream.total_in,
1273
                 "total_out %d\n", d_stream.avail_in, d_stream.total_in,
1262
                 d_stream.avail_out, d_stream.total_out));
1274
                 d_stream.avail_out, d_stream.total_out));
1263
        if (d_stream.avail_out == 0) {
1275
        if (d_stream.avail_out == 0) {
1264
            if ((outp = (char*)allocmem(outp, inlen, &alloc, 
1276
            if ((outp = (char*)allocmem(outp, inlen, &alloc, 
1265
                    imul, mxinc)) == 0) {
1277
                                     imul, mxinc)) == 0) {
1266
                LOGERR(("Inflate: out of memory, current alloc %d\n", 
1278
                LOGERR(("Inflate: out of memory, current alloc %d\n", 
1267
                        alloc*inlen));
1279
                        alloc*inlen));
1268
                inflateEnd(&d_stream);
1280
                inflateEnd(&d_stream);
1269
                return false;
1281
                return false;
1270
            } else {
1282
            } else {
...
...
1345
    string nfn = ncc->getpath();
1357
    string nfn = ncc->getpath();
1346
    if (!ncc->create(off_t(newmbs) * 1000 * 1024, 
1358
    if (!ncc->create(off_t(newmbs) * 1000 * 1024, 
1347
                     CirCache::CC_CRUNIQUE | CirCache::CC_CRTRUNCATE)) {
1359
                     CirCache::CC_CRUNIQUE | CirCache::CC_CRTRUNCATE)) {
1348
        cerr << "Cant create new file in " << tmpdir << " : " << 
1360
        cerr << "Cant create new file in " << tmpdir << " : " << 
1349
            ncc->getReason() << endl;
1361
            ncc->getReason() << endl;
1350
    return false;
1362
     return false;
1351
    }
1363
    }
1352
1364
1353
    bool eof = false;
1365
    bool eof = false;
1354
    occ->rewind(eof);
1366
  if (!occ->rewind(eof)) {
1367
      if (!eof) {
1368
          cerr << "Initial rewind failed" << endl;
1369
          return false;
1370
      }
1371
  }
1355
    int nentries = 0;
1372
    int nentries = 0;
1356
    while (!eof) {
1373
    while (!eof) {
1357
        string udi, sdic, data;
1374
        string udi, sdic, data;
1358
        if (!occ->getCurrent(udi, sdic, data)) {
1375
        if (!occ->getCurrent(udi, sdic, data)) {
1359
            cerr << "getCurrent failed: " << occ->getReason() << endl;
1376
            cerr << "getCurrent failed: " << occ->getReason() << endl;
...
...
1400
}
1417
}
1401
1418
1402
1419
1403
static char *thisprog;
1420
static char *thisprog;
1404
1421
1405
static char usage [] =
1422
static char usage [] = 
1406
    " -c [-u] <dirname> : create\n"
1423
" -c [-u] <dirname> : create\n"
1407
    " -p <dirname> <apath> [apath ...] : put files\n"
1424
" -p <dirname> <apath> [apath ...] : put files\n"
1408
    " -d <dirname> : dump\n"
1425
" -d <dirname> : dump\n"
1409
    " -g [-i instance] [-D] <dirname> <udi>: get\n"
1426
" -g [-i instance] [-D] <dirname> <udi>: get\n"
1410
    "   -D: also dump data\n"
1427
"   -D: also dump data\n"
1411
    " -e <dirname> <udi> : erase\n"
1428
" -e <dirname> <udi> : erase\n"
1412
    " -s <dirname> <newmbs> : resize\n"
1429
" -s <dirname> <newmbs> : resize\n"
1413
    ;
1430
;
1414
static void
1431
static void
1415
Usage(FILE *fp = stderr)
1432
Usage(FILE *fp = stderr)
1416
{
1433
{
1417
    fprintf(fp, "%s: usage:\n%s", thisprog, usage);
1434
    fprintf(fp, "%s: usage:\n%s", thisprog, usage);
1418
    exit(1);
1435
    exit(1);
...
...
1436
1453
1437
    thisprog = argv[0];
1454
    thisprog = argv[0];
1438
    argc--; argv++;
1455
    argc--; argv++;
1439
1456
1440
    while (argc > 0 && **argv == '-') {
1457
    while (argc > 0 && **argv == '-') {
1441
    (*argv)++;
1458
     (*argv)++;
1442
    if (!(**argv))
1459
     if (!(**argv))
1443
        /* Cas du "adb - core" */
1460
          /* Cas du "adb - core" */
1444
        Usage();
1461
          Usage();
1445
    while (**argv)
1462
     while (**argv)
1446
        switch (*(*argv)++) {
1463
          switch (*(*argv)++) {
1447
        case 'c':    op_flags |= OPT_c; break;
1464
          case 'c':  op_flags |= OPT_c; break;
1448
        case 'D':    op_flags |= OPT_D; break;
1465
          case 'D':  op_flags |= OPT_D; break;
1449
        case 'd':    op_flags |= OPT_d; break;
1466
          case 'd':  op_flags |= OPT_d; break;
1450
        case 'e':    op_flags |= OPT_e; break;
1467
          case 'e':  op_flags |= OPT_e; break;
1451
        case 'g':    op_flags |= OPT_g; break;
1468
          case 'g':  op_flags |= OPT_g; break;
1452
        case 'i':    op_flags |= OPT_i; if (argc < 2)  Usage();
1469
          case 'i':  op_flags |= OPT_i; if (argc < 2)  Usage();
1453
        if ((sscanf(*(++argv), "%d", &instance)) != 1) 
1470
             if ((sscanf(*(++argv), "%d", &instance)) != 1) 
1454
            Usage(); 
1471
                  Usage(); 
1455
        argc--; 
1472
             argc--; 
1456
        goto b1;
1473
             goto b1;
1457
        case 'p':    op_flags |= OPT_p; break;
1474
          case 'p':  op_flags |= OPT_p; break;
1458
        case 's':    op_flags |= OPT_s; break;
1475
          case 's':  op_flags |= OPT_s; break;
1459
        case 'u':    op_flags |= OPT_u; break;
1476
          case 'u':  op_flags |= OPT_u; break;
1460
        default: Usage();    break;
1477
          default: Usage();  break;
1461
      }
1478
          }
1462
    b1: argc--; argv++;
1479
    b1: argc--; argv++;
1463
    }
1480
    }
1464
1481
1465
    DebugLog::getdbl()->setloglevel(DEBERR);
1482
    DebugLog::getdbl()->setloglevel(DEBERR);
1466
    DebugLog::setfilename("stderr");
1483
    DebugLog::setfilename("stderr");
1467
1484
1468
    if (argc < 1)
1485
    if (argc < 1)
1469
    Usage();
1486
     Usage();
1470
    string dir = *argv++;argc--;
1487
    string dir = *argv++;argc--;
1471
1488
1472
    CirCache cc(dir);
1489
    CirCache cc(dir);
1473
1490
1474
    if (op_flags & OPT_c) {
1491
    if (op_flags & OPT_c) {
1475
    int flags = 0;
1492
     int flags = 0;
1476
    if (op_flags & OPT_u)
1493
     if (op_flags & OPT_u)
1477
        flags |= CirCache::CC_CRUNIQUE;
1494
          flags |= CirCache::CC_CRUNIQUE;
1478
    if (!cc.create(100*1024, flags)) {
1495
     if (!cc.create(100*1024, flags)) {
1479
        cerr << "Create failed:" << cc.getReason() << endl;
1496
          cerr << "Create failed:" << cc.getReason() << endl;
1480
        exit(1);
1497
          exit(1);
1481
    }
1498
     }
1482
    } else if (op_flags & OPT_s) {
1499
    } else if (op_flags & OPT_s) {
1483
        if (argc != 1) {
1500
        if (argc != 1) {
1484
            Usage();
1501
            Usage();
1485
        }
1502
        }
1486
        int newmbs = atoi(*argv++);argc--;
1503
        int newmbs = atoi(*argv++);argc--;
1487
        if (!resizecc(dir, newmbs)) {
1504
        if (!resizecc(dir, newmbs)) {
1488
            exit(1);
1505
            exit(1);
1489
        }
1506
        }
1490
    } else if (op_flags & OPT_p) {
1507
    } else if (op_flags & OPT_p) {
1491
    if (argc < 1)
1508
     if (argc < 1)
1492
        Usage();
1509
          Usage();
1493
    if (!cc.open(CirCache::CC_OPWRITE)) {
1510
     if (!cc.open(CirCache::CC_OPWRITE)) {
1494
        cerr << "Open failed: " << cc.getReason() << endl;
1511
          cerr << "Open failed: " << cc.getReason() << endl;
1495
        exit(1);
1512
          exit(1);
1496
    }
1513
     }
1497
    while (argc) {
1514
     while (argc) {
1498
        string fn = *argv++;argc--;
1515
          string fn = *argv++;argc--;
1499
        char dic[1000];
1516
          char dic[1000];
1500
        string data, reason;
1517
          string data, reason;
1501
        if (!file_to_string(fn, data, &reason)) {
1518
          if (!file_to_string(fn, data, &reason)) {
1502
        cerr << "File_to_string: " << reason << endl;
1519
             cerr << "File_to_string: " << reason << endl;
1503
        exit(1);
1520
             exit(1);
1504
      }
1521
          }
1505
        string udi;
1522
          string udi;
1506
        make_udi(fn, "", udi);
1523
          make_udi(fn, "", udi);
1507
        sprintf(dic, "#whatever...\nmimetype = text/plain\nudi=%s\n", 
1524
          sprintf(dic, "#whatever...\nmimetype = text/plain\nudi=%s\n", 
1508
            udi.c_str());
1525
                  udi.c_str());
1509
        string sdic;
1526
          string sdic;
1510
        sdic.assign(dic, strlen(dic));
1527
          sdic.assign(dic, strlen(dic));
1511
        ConfSimple conf(sdic);
1528
          ConfSimple conf(sdic);
1512
   
1529
   
1513
        if (!cc.put(udi, &conf, data, 0)) {
1530
          if (!cc.put(udi, &conf, data, 0)) {
1514
        cerr << "Put failed: " << cc.getReason() << endl;
1531
             cerr << "Put failed: " << cc.getReason() << endl;
1515
        cerr << "conf: ["; conf.write(cerr); cerr << "]" << endl;
1532
             cerr << "conf: ["; conf.write(cerr); cerr << "]" << endl;
1516
        exit(1);
1533
             exit(1);
1517
      }
1534
          }
1518
    }
1535
     }
1519
    cc.open(CirCache::CC_OPREAD);
1536
     cc.open(CirCache::CC_OPREAD);
1520
    } else if (op_flags & OPT_g) {
1537
    } else if (op_flags & OPT_g) {
1521
    if (!cc.open(CirCache::CC_OPREAD)) {
1538
     if (!cc.open(CirCache::CC_OPREAD)) {
1522
        cerr << "Open failed: " << cc.getReason() << endl;
1539
          cerr << "Open failed: " << cc.getReason() << endl;
1523
        exit(1);
1540
          exit(1);
1524
    }
1541
     }
1525
    while (argc) {
1542
     while (argc) {
1526
        string udi = *argv++;argc--;
1543
          string udi = *argv++;argc--;
1527
        string dic, data;
1544
          string dic, data;
1528
        if (!cc.get(udi, dic, data, instance)) {
1545
          if (!cc.get(udi, dic, data, instance)) {
1529
        cerr << "Get failed: " << cc.getReason() << endl;
1546
             cerr << "Get failed: " << cc.getReason() << endl;
1530
        exit(1);
1547
             exit(1);
1531
      }
1548
          }
1532
        cout << "Dict: [" << dic << "]" << endl;
1549
          cout << "Dict: [" << dic << "]" << endl;
1533
        if (op_flags & OPT_D)
1550
          if (op_flags & OPT_D)
1534
        cout << "Data: [" << data << "]" << endl;
1551
             cout << "Data: [" << data << "]" << endl;
1535
    }
1552
     }
1536
    } else if (op_flags & OPT_e) {
1553
    } else if (op_flags & OPT_e) {
1537
    if (!cc.open(CirCache::CC_OPWRITE)) {
1554
     if (!cc.open(CirCache::CC_OPWRITE)) {
1538
        cerr << "Open failed: " << cc.getReason() << endl;
1555
          cerr << "Open failed: " << cc.getReason() << endl;
1539
        exit(1);
1556
          exit(1);
1540
    }
1557
     }
1541
    while (argc) {
1558
     while (argc) {
1542
        string udi = *argv++;argc--;
1559
          string udi = *argv++;argc--;
1543
        string dic, data;
1560
          string dic, data;
1544
        if (!cc.erase(udi)) {
1561
          if (!cc.erase(udi)) {
1545
        cerr << "Erase failed: " << cc.getReason() << endl;
1562
             cerr << "Erase failed: " << cc.getReason() << endl;
1546
        exit(1);
1563
             exit(1);
1547
      }
1564
          }
1548
    }
1565
     }
1549
    } else if (op_flags & OPT_d) {
1566
    } else if (op_flags & OPT_d) {
1550
    if (!cc.open(CirCache::CC_OPREAD)) {
1567
     if (!cc.open(CirCache::CC_OPREAD)) {
1551
        cerr << "Open failed: " << cc.getReason() << endl;
1568
          cerr << "Open failed: " << cc.getReason() << endl;
1552
        exit(1);
1569
          exit(1);
1553
    }
1570
     }
1554
    cc.dump();
1571
     cc.dump();
1555
    } else
1572
    } else
1556
    Usage();
1573
     Usage();
1557
1574
1558
    exit(0);
1575
    exit(0);
1559
}
1576
}
1560
1577
1561
#endif
1578
#endif