~ps10gel/ubuntu/xenial/trafficserver/6.2.0

« back to all changes in this revision

Viewing changes to iocore/cache/Cache.cc

  • Committer: Package Import Robot
  • Author(s): Aron Xu
  • Date: 2013-05-09 01:00:04 UTC
  • mto: (1.1.11) (5.3.3 experimental)
  • mto: This revision was merged to the branch mainline in revision 15.
  • Revision ID: package-import@ubuntu.com-20130509010004-9fqq9n0adseg3f8w
Tags: upstream-3.3.2
ImportĀ upstreamĀ versionĀ 3.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
79
79
int cache_config_read_while_writer = 0;
80
80
char cache_system_config_directory[PATH_NAME_MAX + 1];
81
81
int cache_config_mutex_retry_delay = 2;
 
82
#ifdef HTTP_CACHE
 
83
static int enable_cache_empty_http_doc = 0;
 
84
#endif
82
85
 
83
86
// Globals
84
87
 
146
149
  }
147
150
};
148
151
 
 
152
#if AIO_MODE == AIO_MODE_NATIVE
 
153
struct VolInit : public Continuation
 
154
{
 
155
  Vol *vol;
 
156
  char *path;
 
157
  off_t blocks;
 
158
  int64_t offset;
 
159
  bool vol_clear;
 
160
 
 
161
  int mainEvent(int event, Event *e) {
 
162
    vol->init(path, blocks, offset, vol_clear);
 
163
    mutex.clear();
 
164
    delete this;
 
165
    return EVENT_DONE;
 
166
  }
 
167
 
 
168
  VolInit(Vol *v, char *p, off_t b, int64_t o, bool c) : Continuation(v->mutex),
 
169
    vol(v), path(p), blocks(b), offset(o), vol_clear(c) {
 
170
    SET_HANDLER(&VolInit::mainEvent);
 
171
  }
 
172
};
 
173
 
 
174
struct DiskInit : public Continuation
 
175
{
 
176
  CacheDisk *disk;
 
177
  char *s;
 
178
  off_t blocks;
 
179
  off_t askip;
 
180
  int ahw_sector_size;
 
181
  int fildes;
 
182
  bool clear;
 
183
 
 
184
  int mainEvent(int event, Event *e) {
 
185
    disk->open(s, blocks, askip, ahw_sector_size, fildes, clear);
 
186
    mutex.clear();
 
187
    delete this;
 
188
    return EVENT_DONE;
 
189
  }
 
190
 
 
191
  DiskInit(CacheDisk *d, char *str, off_t b, off_t skip, int sector, int f, bool c) : Continuation(d->mutex),
 
192
      disk(d), s(str), blocks(b), askip(skip), ahw_sector_size(sector), fildes(f), clear(c) {
 
193
    SET_HANDLER(&DiskInit::mainEvent);
 
194
  }
 
195
};
 
196
#endif
149
197
void cplist_init();
150
198
static void cplist_update();
151
199
int cplist_reconfigure();
176
224
    start = volume - 1;
177
225
    end = volume;
178
226
  }
179
 
  
 
227
 
180
228
  for (int i = start; i < end; i++) {
181
229
    if (!DISK_BAD(gvol[i]->disk)) {
182
230
      if (!gvol[i]->header->cycle)
214
262
  if (new_value) {
215
263
    float http_bg_fill;
216
264
 
217
 
    IOCORE_ReadConfigFloat(http_bg_fill, "proxy.config.http.background_fill_completed_threshold");
 
265
    REC_ReadConfigFloat(http_bg_fill, "proxy.config.http.background_fill_completed_threshold");
218
266
    if (http_bg_fill > 0.0) {
219
267
      Note("to enable reading while writing a document, %s should be 0.0: read while writing disabled",
220
268
           "proxy.config.http.background_fill_completed_threshold");
413
461
    ainfo->object_key_set(earliest_key);
414
462
    // don't know the total len yet
415
463
  }
 
464
  if (enable_cache_empty_http_doc) {
 
465
    MIMEField *field = ainfo->m_alt->m_response_hdr.field_find(MIME_FIELD_CONTENT_LENGTH, MIME_LEN_CONTENT_LENGTH);
 
466
    if (field && !field->value_get_int64()) 
 
467
      f.allow_empty_doc = 1;
 
468
    else
 
469
      f.allow_empty_doc = 0;
 
470
  } else 
 
471
    f.allow_empty_doc = 0;
416
472
  alternate.copy_shallow(ainfo);
417
473
  ainfo->clear();
418
474
}
530
586
  verify_cache_api();
531
587
#endif
532
588
 
 
589
#if AIO_MODE == AIO_MODE_NATIVE
 
590
  int etype = ET_NET;
 
591
  int n_netthreads = eventProcessor.n_threads_for_type[etype];
 
592
  EThread **netthreads = eventProcessor.eventthread[etype];
 
593
  for (int i = 0; i < n_netthreads; ++i) {
 
594
    netthreads[i]->diskHandler = new DiskHandler();
 
595
    netthreads[i]->schedule_imm(netthreads[i]->diskHandler);
 
596
  }
 
597
#endif
 
598
 
533
599
  start_internal_flags = flags;
534
600
  clear = !!(flags & PROCESSOR_RECONFIGURE) || auto_clear_flag;
535
601
  fix = !!(flags & PROCESSOR_FIX);
593
659
        }
594
660
        off_t skip = ROUND_TO_STORE_BLOCK((sd->offset < START_POS ? START_POS + sd->alignment : sd->offset));
595
661
        blocks = blocks - ROUND_TO_STORE_BLOCK(sd->offset + skip);
 
662
#if AIO_MODE == AIO_MODE_NATIVE
 
663
        eventProcessor.schedule_imm(NEW(new DiskInit(gdisks[gndisks], path, blocks, skip, sector_size, fd, clear)));
 
664
#else
596
665
        gdisks[gndisks]->open(path, blocks, skip, sector_size, fd, clear);
 
666
#endif
597
667
        gndisks++;
598
668
      }
599
669
    } else {
877
947
      switch (cache_config_ram_cache_compress) {
878
948
        default:
879
949
          Fatal("unknown RAM cache compression type: %d", cache_config_ram_cache_compress);
880
 
        case CACHE_COMPRESSION_NONE: 
 
950
        case CACHE_COMPRESSION_NONE:
881
951
        case CACHE_COMPRESSION_FASTLZ:
882
952
          break;
883
953
        case CACHE_COMPRESSION_LIBZ:
1106
1176
    aio->aiocb.aio_buf = &(init_info->vol_h_f[i * STORE_BLOCK_SIZE]);
1107
1177
    aio->aiocb.aio_nbytes = footerlen;
1108
1178
    aio->action = this;
1109
 
    aio->thread = this_ethread();
 
1179
    aio->thread = AIO_CALLBACK_THREAD_ANY;
1110
1180
    aio->then = (i < 3) ? &(init_info->vol_aio[i + 1]) : 0;
1111
1181
  }
1112
 
 
1113
 
  eventProcessor.schedule_imm(this, ET_CALL);
 
1182
#if AIO_MODE == AIO_MODE_NATIVE
 
1183
  ink_assert(ink_aio_readv(init_info->vol_aio));
 
1184
#else
 
1185
  ink_assert(ink_aio_read(init_info->vol_aio));
 
1186
#endif
1114
1187
  return 0;
1115
1188
}
1116
1189
 
1440
1513
    init_info->vol_aio[2].aiocb.aio_offset = ss + dirlen - footerlen;
1441
1514
 
1442
1515
    SET_HANDLER(&Vol::handle_recover_write_dir);
 
1516
#if AIO_MODE == AIO_MODE_NATIVE
 
1517
    ink_assert(ink_aio_writev(init_info->vol_aio));
 
1518
#else
1443
1519
    ink_assert(ink_aio_write(init_info->vol_aio));
 
1520
#endif
1444
1521
    return EVENT_CONT;
1445
1522
  }
1446
1523
 
1474
1551
  AIOCallback *op;
1475
1552
  VolHeaderFooter *hf[4];
1476
1553
  switch (event) {
1477
 
  case EVENT_IMMEDIATE:
1478
 
  case EVENT_INTERVAL:
1479
 
    ink_assert(ink_aio_read(init_info->vol_aio));
1480
 
    return EVENT_CONT;
1481
 
 
1482
1554
  case AIO_EVENT_DONE:
1483
1555
    op = (AIOCallback *) data;
1484
1556
    for (int i = 0; i < 4; i++) {
1520
1592
      delete init_info;
1521
1593
      init_info = 0;
1522
1594
    }
1523
 
 
1524
1595
    return EVENT_DONE;
 
1596
  default:
 
1597
    ink_assert(!"not reach here");
1525
1598
  }
1526
1599
  return EVENT_DONE;
1527
1600
}
1693
1766
        char message[128];
1694
1767
        snprintf(message, sizeof(message), "Error accessing Disk %s", d->path);
1695
1768
        Warning("%s", message);
1696
 
        IOCORE_SignalManager(REC_SIGNAL_CACHE_WARNING, message);
 
1769
        REC_SignalManager(REC_SIGNAL_CACHE_WARNING, message);
1697
1770
      } else if (!DISK_BAD_SIGNALLED(d)) {
1698
1771
 
1699
1772
        char message[128];
1700
1773
        snprintf(message, sizeof(message), "too many errors accessing disk %s: declaring disk bad", d->path);
1701
1774
        Warning("%s", message);
1702
 
        IOCORE_SignalManager(REC_SIGNAL_CACHE_ERROR, message);
 
1775
        REC_SignalManager(REC_SIGNAL_CACHE_ERROR, message);
1703
1776
        /* subtract the disk space that was being used from  the cache size stat */
1704
1777
        // dir entries stat
1705
1778
        int p;
1794
1867
  total_nvol = 0;
1795
1868
  total_good_nvol = 0;
1796
1869
 
1797
 
  IOCORE_EstablishStaticConfigInt32(cache_config_min_average_object_size, "proxy.config.cache.min_average_object_size");
 
1870
  REC_EstablishStaticConfigInt32(cache_config_min_average_object_size, "proxy.config.cache.min_average_object_size");
1798
1871
  Debug("cache_init", "Cache::open - proxy.config.cache.min_average_object_size = %d",
1799
1872
        (int)cache_config_min_average_object_size);
1800
1873
 
1816
1889
            blocks = q->b->len;
1817
1890
 
1818
1891
            bool vol_clear = clear || d->cleared || q->new_block;
 
1892
#if AIO_MODE == AIO_MODE_NATIVE
 
1893
            eventProcessor.schedule_imm(NEW(new VolInit(cp->vols[vol_no], d->path, blocks, q->b->offset, vol_clear)));
 
1894
#else
1819
1895
            cp->vols[vol_no]->init(d->path, blocks, q->b->offset, vol_clear);
 
1896
#endif
1820
1897
            vol_no++;
1821
1898
            cache_size += blocks;
1822
1899
          }
1847
1924
bool
1848
1925
CacheVC::is_pread_capable()
1849
1926
{
1850
 
  return alternate.get_frag_offset_count() > 0;
 
1927
  return !f.read_from_writer_called;
1851
1928
}
1852
1929
 
1853
1930
#define STORE_COLLISION 1
1930
2007
        if (checksum != doc->checksum) {
1931
2008
          Note("cache: checksum error for [%" PRIu64 " %" PRIu64 "] len %d, hlen %d, disk %s, offset %" PRIu64 " size %zu",
1932
2009
               doc->first_key.b[0], doc->first_key.b[1],
1933
 
               doc->len, doc->hlen, vol->path, io.aiocb.aio_offset, io.aiocb.aio_nbytes);
 
2010
               doc->len, doc->hlen, vol->path, io.aiocb.aio_offset, (size_t)io.aiocb.aio_nbytes);
1934
2011
          doc->magic = DOC_CORRUPT;
1935
2012
          okay = 0;
1936
2013
        }
2525
2602
      full_disks += 1;
2526
2603
      if (full_disks == gndisks) {
2527
2604
        char config_file[PATH_NAME_MAX];
2528
 
        IOCORE_ReadConfigString(config_file, "proxy.config.cache.volume_filename", PATH_NAME_MAX);
 
2605
        REC_ReadConfigString(config_file, "proxy.config.cache.volume_filename", PATH_NAME_MAX);
2529
2606
        if (cp->size)
2530
2607
          Warning("not enough space to increase volume: [%d] to size: [%" PRId64 "]",
2531
2608
                  volume_number, (int64_t)((to_create + cp->size) >> (20 - STORE_BLOCK_SHIFT)));
2677
2754
 
2678
2755
  cache_rsb = RecAllocateRawStatBlock((int) cache_stat_count);
2679
2756
 
2680
 
  IOCORE_EstablishStaticConfigInteger(cache_config_ram_cache_size, "proxy.config.cache.ram_cache.size");
 
2757
  REC_EstablishStaticConfigInteger(cache_config_ram_cache_size, "proxy.config.cache.ram_cache.size");
2681
2758
  Debug("cache_init", "proxy.config.cache.ram_cache.size = %" PRId64 " = %" PRId64 "Mb",
2682
2759
        cache_config_ram_cache_size, cache_config_ram_cache_size / (1024 * 1024));
2683
2760
 
2684
 
  IOCORE_EstablishStaticConfigInt32(cache_config_ram_cache_algorithm, "proxy.config.cache.ram_cache.algorithm");
2685
 
  IOCORE_EstablishStaticConfigInt32(cache_config_ram_cache_compress, "proxy.config.cache.ram_cache.compress");
2686
 
  IOCORE_EstablishStaticConfigInt32(cache_config_ram_cache_compress_percent, "proxy.config.cache.ram_cache.compress_percent");
2687
 
  IOCORE_EstablishStaticConfigInt32(cache_config_ram_cache_use_seen_filter, "proxy.config.cache.ram_cache.use_seen_filter");
 
2761
  REC_EstablishStaticConfigInt32(cache_config_ram_cache_algorithm, "proxy.config.cache.ram_cache.algorithm");
 
2762
  REC_EstablishStaticConfigInt32(cache_config_ram_cache_compress, "proxy.config.cache.ram_cache.compress");
 
2763
  REC_EstablishStaticConfigInt32(cache_config_ram_cache_compress_percent, "proxy.config.cache.ram_cache.compress_percent");
 
2764
  REC_EstablishStaticConfigInt32(cache_config_ram_cache_use_seen_filter, "proxy.config.cache.ram_cache.use_seen_filter");
2688
2765
 
2689
 
  IOCORE_EstablishStaticConfigInt32(cache_config_http_max_alts, "proxy.config.cache.limits.http.max_alts");
 
2766
  REC_EstablishStaticConfigInt32(cache_config_http_max_alts, "proxy.config.cache.limits.http.max_alts");
2690
2767
  Debug("cache_init", "proxy.config.cache.limits.http.max_alts = %d", cache_config_http_max_alts);
2691
2768
 
2692
 
  IOCORE_EstablishStaticConfigInteger(cache_config_ram_cache_cutoff, "proxy.config.cache.ram_cache_cutoff");
 
2769
  REC_EstablishStaticConfigInteger(cache_config_ram_cache_cutoff, "proxy.config.cache.ram_cache_cutoff");
2693
2770
  Debug("cache_init", "cache_config_ram_cache_cutoff = %" PRId64 " = %" PRId64 "Mb",
2694
2771
        cache_config_ram_cache_cutoff, cache_config_ram_cache_cutoff / (1024 * 1024));
2695
2772
 
2696
 
  IOCORE_EstablishStaticConfigInt32(cache_config_permit_pinning, "proxy.config.cache.permit.pinning");
 
2773
  REC_EstablishStaticConfigInt32(cache_config_permit_pinning, "proxy.config.cache.permit.pinning");
2697
2774
  Debug("cache_init", "proxy.config.cache.permit.pinning = %d", cache_config_permit_pinning);
2698
2775
 
2699
 
  IOCORE_EstablishStaticConfigInt32(cache_config_dir_sync_frequency, "proxy.config.cache.dir.sync_frequency");
 
2776
  REC_EstablishStaticConfigInt32(cache_config_dir_sync_frequency, "proxy.config.cache.dir.sync_frequency");
2700
2777
  Debug("cache_init", "proxy.config.cache.dir.sync_frequency = %d", cache_config_dir_sync_frequency);
2701
2778
 
2702
 
  IOCORE_EstablishStaticConfigInt32(cache_config_vary_on_user_agent, "proxy.config.cache.vary_on_user_agent");
 
2779
  REC_EstablishStaticConfigInt32(cache_config_vary_on_user_agent, "proxy.config.cache.vary_on_user_agent");
2703
2780
  Debug("cache_init", "proxy.config.cache.vary_on_user_agent = %d", cache_config_vary_on_user_agent);
2704
2781
 
2705
 
  IOCORE_EstablishStaticConfigInt32(cache_config_select_alternate, "proxy.config.cache.select_alternate");
 
2782
  REC_EstablishStaticConfigInt32(cache_config_select_alternate, "proxy.config.cache.select_alternate");
2706
2783
  Debug("cache_init", "proxy.config.cache.select_alternate = %d", cache_config_select_alternate);
2707
2784
 
2708
 
  IOCORE_EstablishStaticConfigInt32(cache_config_max_doc_size, "proxy.config.cache.max_doc_size");
 
2785
  REC_EstablishStaticConfigInt32(cache_config_max_doc_size, "proxy.config.cache.max_doc_size");
2709
2786
  Debug("cache_init", "proxy.config.cache.max_doc_size = %d = %dMb",
2710
2787
        cache_config_max_doc_size, cache_config_max_doc_size / (1024 * 1024));
2711
2788
 
2712
 
  IOCORE_EstablishStaticConfigInt32(cache_config_mutex_retry_delay, "proxy.config.cache.mutex_retry_delay");
 
2789
  REC_EstablishStaticConfigInt32(cache_config_mutex_retry_delay, "proxy.config.cache.mutex_retry_delay");
2713
2790
  Debug("cache_init", "proxy.config.cache.mutex_retry_delay = %dms", cache_config_mutex_retry_delay);
2714
2791
 
2715
2792
  // This is just here to make sure IOCORE "standalone" works, it's usually configured in RecordsConfig.cc
2716
 
  IOCORE_RegisterConfigString(RECT_CONFIG, "proxy.config.config_dir", TS_BUILD_SYSCONFDIR, RECU_DYNAMIC, RECC_NULL, NULL);
2717
 
  IOCORE_ReadConfigString(cache_system_config_directory, "proxy.config.config_dir", PATH_NAME_MAX);
 
2793
  RecRegisterConfigString(RECT_CONFIG, "proxy.config.config_dir", TS_BUILD_SYSCONFDIR, RECU_DYNAMIC, RECC_NULL, NULL);
 
2794
  REC_ReadConfigString(cache_system_config_directory, "proxy.config.config_dir", PATH_NAME_MAX);
2718
2795
  if (cache_system_config_directory[0] != '/') {
2719
2796
    // Not an absolute path so use system one
2720
2797
    Layout::get()->relative(cache_system_config_directory, sizeof(cache_system_config_directory), cache_system_config_directory);
2733
2810
  }
2734
2811
  // TODO: These are left here, since they are only registered if HIT_EVACUATE is enabled.
2735
2812
#ifdef HIT_EVACUATE
2736
 
  IOCORE_EstablishStaticConfigInt32(cache_config_hit_evacuate_percent, "proxy.config.cache.hit_evacuate_percent");
 
2813
  REC_EstablishStaticConfigInt32(cache_config_hit_evacuate_percent, "proxy.config.cache.hit_evacuate_percent");
2737
2814
  Debug("cache_init", "proxy.config.cache.hit_evacuate_percent = %d", cache_config_hit_evacuate_percent);
2738
2815
 
2739
 
  IOCORE_EstablishStaticConfigInt32(cache_config_hit_evacuate_size_limit, "proxy.config.cache.hit_evacuate_size_limit");
 
2816
  REC_EstablishStaticConfigInt32(cache_config_hit_evacuate_size_limit, "proxy.config.cache.hit_evacuate_size_limit");
2740
2817
  Debug("cache_init", "proxy.config.cache.hit_evacuate_size_limit = %d", cache_config_hit_evacuate_size_limit);
2741
2818
#endif
2742
2819
 
2743
 
  IOCORE_EstablishStaticConfigInt32(cache_config_force_sector_size, "proxy.config.cache.force_sector_size");
2744
 
  IOCORE_EstablishStaticConfigInt32(cache_config_target_fragment_size, "proxy.config.cache.target_fragment_size");
 
2820
  REC_EstablishStaticConfigInt32(cache_config_force_sector_size, "proxy.config.cache.force_sector_size");
 
2821
  REC_EstablishStaticConfigInt32(cache_config_target_fragment_size, "proxy.config.cache.target_fragment_size");
2745
2822
 
2746
2823
  if (cache_config_target_fragment_size == 0)
2747
2824
    cache_config_target_fragment_size = DEFAULT_TARGET_FRAGMENT_SIZE;
2751
2828
 
2752
2829
  //  # 0 - MD5 hash
2753
2830
  //  # 1 - MMH hash
2754
 
  IOCORE_EstablishStaticConfigInt32(url_hash_method, "proxy.config.cache.url_hash_method");
 
2831
  REC_EstablishStaticConfigInt32(url_hash_method, "proxy.config.cache.url_hash_method");
2755
2832
  Debug("cache_init", "proxy.config.cache.url_hash_method = %d", url_hash_method);
 
2833
  REC_EstablishStaticConfigInt32(enable_cache_empty_http_doc, "proxy.config.http.cache.allow_empty_doc");
2756
2834
#endif
2757
2835
 
2758
 
  IOCORE_EstablishStaticConfigInt32(cache_config_max_disk_errors, "proxy.config.cache.max_disk_errors");
 
2836
  REC_EstablishStaticConfigInt32(cache_config_max_disk_errors, "proxy.config.cache.max_disk_errors");
2759
2837
  Debug("cache_init", "proxy.config.cache.max_disk_errors = %d", cache_config_max_disk_errors);
2760
2838
 
2761
 
  IOCORE_EstablishStaticConfigInt32(cache_config_agg_write_backlog, "proxy.config.cache.agg_write_backlog");
 
2839
  REC_EstablishStaticConfigInt32(cache_config_agg_write_backlog, "proxy.config.cache.agg_write_backlog");
2762
2840
  Debug("cache_init", "proxy.config.cache.agg_write_backlog = %d", cache_config_agg_write_backlog);
2763
2841
 
2764
 
  IOCORE_EstablishStaticConfigInt32(cache_config_enable_checksum, "proxy.config.cache.enable_checksum");
 
2842
  REC_EstablishStaticConfigInt32(cache_config_enable_checksum, "proxy.config.cache.enable_checksum");
2765
2843
  Debug("cache_init", "proxy.config.cache.enable_checksum = %d", cache_config_enable_checksum);
2766
2844
 
2767
 
  IOCORE_EstablishStaticConfigInt32(cache_config_alt_rewrite_max_size, "proxy.config.cache.alt_rewrite_max_size");
 
2845
  REC_EstablishStaticConfigInt32(cache_config_alt_rewrite_max_size, "proxy.config.cache.alt_rewrite_max_size");
2768
2846
  Debug("cache_init", "proxy.config.cache.alt_rewrite_max_size = %d", cache_config_alt_rewrite_max_size);
2769
2847
 
2770
 
  IOCORE_EstablishStaticConfigInt32(cache_config_read_while_writer, "proxy.config.cache.enable_read_while_writer");
 
2848
  REC_EstablishStaticConfigInt32(cache_config_read_while_writer, "proxy.config.cache.enable_read_while_writer");
2771
2849
  cache_config_read_while_writer = validate_rww(cache_config_read_while_writer);
2772
 
  IOCORE_RegisterConfigUpdateFunc("proxy.config.cache.enable_read_while_writer", update_cache_config, NULL);
 
2850
  REC_RegisterConfigUpdateFunc("proxy.config.cache.enable_read_while_writer", update_cache_config, NULL);
2773
2851
  Debug("cache_init", "proxy.config.cache.enable_read_while_writer = %d", cache_config_read_while_writer);
2774
2852
 
2775
2853
  register_cache_stats(cache_rsb, "proxy.process.cache");
2784
2862
  if (theCacheStore.n_disks == 0) {
2785
2863
    char p[PATH_NAME_MAX + 1];
2786
2864
    snprintf(p, sizeof(p), "%s/", cache_system_config_directory);
2787
 
    IOCORE_ReadConfigString(p + strlen(p), "proxy.config.cache.storage_filename", PATH_NAME_MAX - strlen(p) - 1);
 
2865
    REC_ReadConfigString(p + strlen(p), "proxy.config.cache.storage_filename", PATH_NAME_MAX - strlen(p) - 1);
2788
2866
    if (p[strlen(p) - 1] == '/' || p[strlen(p) - 1] == '\\') {
2789
2867
      ink_strlcat(p, "storage.config", sizeof(p));
2790
2868
    }