/** * gtags_next: return next record. * * @param[in] gtop #GTOP structure * @return record * @VAR{NULL} end of tag */ GTP * gtags_next(GTOP *gtop) { gtop->readcount++; if (gtop->flags & GTOP_PATH) { if (gtop->path_index >= gtop->path_count) return NULL; gtop->gtp.path = gtop->path_array[gtop->path_index++]; return >op->gtp; } else if (gtop->flags & GTOP_KEY) { gtop->gtp.tag = dbop_next(gtop->dbop); again3: for (; gtop->gtp.tag != NULL; gtop->gtp.tag = dbop_next(gtop->dbop)) { VIRTUAL_GRTAGS_GSYMS_PROCESSING(gtop); break; } if (gtop->gtp.tag == NULL) { if (gtop->prefix && gtags_restart(gtop)) { gtop->gtp.tag = dbop_first(gtop->dbop, gtop->key, gtop->preg, gtop->dbflags); goto again3; } } return gtop->gtp.tag ? >op->gtp : NULL; } else { /* * End of segment. * Reset resources and read new segment again. */ if (gtop->gtp_index >= gtop->gtp_count) { varray_reset(gtop->vb); pool_reset(gtop->segment_pool); /* strhash_reset(gtop->path_hash); */ segment_read(gtop); } if (gtop->gtp_index >= gtop->gtp_count) { if (gtop->prefix && gtags_restart(gtop)) { gtop->gtp.tag = dbop_first(gtop->dbop, gtop->key, gtop->preg, gtop->dbflags); if (gtop->gtp.tag == NULL) return NULL; dbop_unread(gtop->dbop); segment_read(gtop); } else return NULL; } return >op->gtp_array[gtop->gtp_index++]; } }
/** * gtags_next: return next record. * * @param[in] gtop #GTOP structure * @return record * @VAR{NULL} end of tag */ GTP * gtags_next(GTOP *gtop) { if (gtop->flags & GTOP_PATH) { if (gtop->path_index >= gtop->path_count) return NULL; gtop->gtp.path = gtop->path_array[gtop->path_index++]; return >op->gtp; } else if (gtop->flags & GTOP_KEY) { for (gtop->gtp.tag = dbop_next(gtop->dbop); gtop->gtp.tag != NULL; gtop->gtp.tag = dbop_next(gtop->dbop)) { VIRTUAL_GRTAGS_GSYMS_PROCESSING(gtop); break; } return gtop->gtp.tag ? >op->gtp : NULL; } else { /* * End of segment. * Reset resources and read new segment again. */ if (gtop->gtp_index >= gtop->gtp_count) { varray_reset(gtop->vb); pool_reset(gtop->segment_pool); /* strhash_reset(gtop->path_hash); */ segment_read(gtop); } if (gtop->gtp_index >= gtop->gtp_count) return NULL; return >op->gtp_array[gtop->gtp_index++]; } }
int wad_segment_read() { int fs; int n; WadSegment *s, *lasts; segments = 0; lasts = 0; fs = segment_open(); while (1) { s = (WadSegment *) wad_malloc(sizeof(WadSegment)); skip: n = segment_read(fs,s); if (n <= 0) break; if (wad_file_check(s->vaddr)) goto skip; /* Skip files we already loaded */ s->next = 0; if (!lasts) { segments = s; lasts = s; } else { lasts->next = s; lasts = s; } if (wad_debug_mode & DEBUG_SEGMENT) { wad_printf("wad_segment: read : %08x-%08x, base=%x in %s\n", s->vaddr, ((char *) s->vaddr) + s->size, s->base, s->mappath); } } close(fs); return 0; }
int dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, Dwfl_Memory_Callback *memory_callback, void *memory_callback_arg, Dwfl_Module_Callback *read_eagerly, void *read_eagerly_arg, const struct r_debug_info *r_debug_info) { size_t segment = ndx; if (segment >= dwfl->lookup_elts) segment = dwfl->lookup_elts - 1; while (segment > 0 && (dwfl->lookup_segndx[segment] > ndx || dwfl->lookup_segndx[segment] == -1)) --segment; while (dwfl->lookup_segndx[segment] < ndx) if (++segment == dwfl->lookup_elts) return 0; GElf_Addr start = dwfl->lookup_addr[segment]; inline bool segment_read (int segndx, void **buffer, size_t *buffer_available, GElf_Addr addr, size_t minread) { return ! (*memory_callback) (dwfl, segndx, buffer, buffer_available, addr, minread, memory_callback_arg); } inline void release_buffer (void **buffer, size_t *buffer_available) { if (*buffer != NULL) (void) segment_read (-1, buffer, buffer_available, 0, 0); } /* First read in the file header and check its sanity. */ void *buffer = NULL; size_t buffer_available = INITIAL_READ; inline int finish (void) { release_buffer (&buffer, &buffer_available); return ndx; }
/** * gtags_first: return first record * * @param[in] gtop #GTOP structure * @param[in] pattern tag name <br> * - may be regular expression * - may be @VAR{NULL} * @param[in] flags #GTOP_PREFIX: prefix read <br> * #GTOP_KEY: read key only <br> * #GTOP_PATH: read path only <br> * #GTOP_NOREGEX: don't use regular expression. <br> * #GTOP_IGNORECASE: ignore case distinction. <br> * #GTOP_BASICREGEX: use basic regular expression. <br> * #GTOP_NOSORT: don't sort * @return record */ GTP * gtags_first(GTOP *gtop, const char *pattern, int flags) { int dbflags = 0; int regflags = 0; char prefix[IDENTLEN]; static regex_t reg; regex_t *preg = ® const char *key = NULL; const char *tagline; /* Settlement for last time if any */ if (gtop->path_hash) { strhash_close(gtop->path_hash); gtop->path_hash = NULL; } if (gtop->path_array) { free(gtop->path_array); gtop->path_array = NULL; } gtop->flags = flags; if (flags & GTOP_PREFIX && pattern != NULL) dbflags |= DBOP_PREFIX; if (flags & GTOP_KEY) dbflags |= DBOP_KEY; if (!(flags & GTOP_BASICREGEX)) regflags |= REG_EXTENDED; if (flags & GTOP_IGNORECASE) regflags |= REG_ICASE; /* * Get key and compiled regular expression for dbop_xxxx(). */ if (flags & GTOP_NOREGEX) { key = pattern; preg = NULL; } else if (pattern == NULL || !strcmp(pattern, ".*")) { /* * Since the regular expression '.*' matches to any record, * we take sequential read method. */ key = NULL; preg = NULL; } else if (isregex(pattern) && regcomp(preg, pattern, regflags) == 0) { const char *p; /* * If the pattern include '^' + some non regular expression * characters like '^aaa[0-9]', we take prefix read method * with the non regular expression part as the prefix. */ if (!(flags & GTOP_IGNORECASE) && *pattern == '^' && *(p = pattern + 1) && !isregexchar(*p)) { int i = 0; while (*p && !isregexchar(*p) && i < IDENTLEN) prefix[i++] = *p++; prefix[i] = '\0'; key = prefix; dbflags |= DBOP_PREFIX; } else { key = NULL; } } else { key = pattern; preg = NULL; } /* * If GTOP_PATH is set, at first, we collect all path names in a pool and * sort them. gtags_first() and gtags_next() returns one of the pool. */ if (gtop->flags & GTOP_PATH) { struct sh_entry *entry; char *p; const char *cp; unsigned long i; gtop->path_hash = strhash_open(HASHBUCKETS); /* * Pool path names. * * fid path name * +-------------------------- * |100 ./aaa/a.c * |105 ./aaa/b.c * ... */ for (tagline = dbop_first(gtop->dbop, key, preg, dbflags); tagline != NULL; tagline = dbop_next(gtop->dbop)) { VIRTUAL_GRTAGS_GSYMS_PROCESSING(gtop); /* extract file id */ p = locatestring(tagline, " ", MATCH_FIRST); if (p == NULL) die("Illegal tag record. '%s'\n", tagline); *p = '\0'; entry = strhash_assign(gtop->path_hash, tagline, 1); /* new entry: get path name and set. */ if (entry->value == NULL) { cp = gpath_fid2path(tagline, NULL); if (cp == NULL) die("GPATH is corrupted.(file id '%s' not found)", tagline); entry->value = strhash_strdup(gtop->path_hash, cp, 0); } } /* * Sort path names. * * fid path name path_array (sort) * +-------------------------- +---+ * |100 ./aaa/a.c <-------* | * |105 ./aaa/b.c <-------* | * ... ... */ gtop->path_array = (char **)check_malloc(gtop->path_hash->entries * sizeof(char *)); i = 0; for (entry = strhash_first(gtop->path_hash); entry != NULL; entry = strhash_next(gtop->path_hash)) gtop->path_array[i++] = entry->value; if (i != gtop->path_hash->entries) die("Something is wrong. 'i = %lu, entries = %lu'" , i, gtop->path_hash->entries); if (!(gtop->flags & GTOP_NOSORT)) qsort(gtop->path_array, gtop->path_hash->entries, sizeof(char *), compare_path); gtop->path_count = gtop->path_hash->entries; gtop->path_index = 0; if (gtop->path_index >= gtop->path_count) return NULL; gtop->gtp.path = gtop->path_array[gtop->path_index++]; return >op->gtp; } else if (gtop->flags & GTOP_KEY) { for (gtop->gtp.tag = dbop_first(gtop->dbop, key, preg, dbflags); gtop->gtp.tag != NULL; gtop->gtp.tag = dbop_next(gtop->dbop)) { VIRTUAL_GRTAGS_GSYMS_PROCESSING(gtop); break; } return gtop->gtp.tag ? >op->gtp : NULL; } else { if (gtop->vb == NULL) gtop->vb = varray_open(sizeof(GTP), 200); else varray_reset(gtop->vb); if (gtop->segment_pool == NULL) gtop->segment_pool = pool_open(); else pool_reset(gtop->segment_pool); if (gtop->path_hash == NULL) gtop->path_hash = strhash_open(HASHBUCKETS); else strhash_reset(gtop->path_hash); tagline = dbop_first(gtop->dbop, key, preg, dbflags); if (tagline == NULL) return NULL; /* * Dbop_next() wil read the same record again. */ dbop_unread(gtop->dbop); /* * Read a tag segment with sorting. */ segment_read(gtop); return >op->gtp_array[gtop->gtp_index++]; } }
int main(int argc, char **argv) { int chunk_size = 10; int n_chunks = 10; int bufsize= n_chunks * chunk_size; char base_data[bufsize+1]; char buffer[bufsize+1]; char log1_data[bufsize+1]; char log2_data[bufsize+1]; char log3_data[bufsize+1]; tbuffer_t tbuf; ex_iovec_t ex_iov, ex_iov_table[n_chunks]; int i, err; char *fname = NULL; exnode_t *ex; exnode_exchange_t *exp; segment_t *seg, *clone, *clone2, *clone3; seglog_priv_t *s; opque_t *q; if (argc < 2) { printf("\n"); printf("log_test LIO_COMMON_OPTIONS log.ex3\n"); lio_print_options(stdout); printf(" log.ex3 - Log file to use. IF the file is not empty all it's contents are truncated\n"); printf("\n"); return(1); } lio_init(&argc, &argv); //*** Parse the args //** This is the remote file to download i = 1; fname = argv[i]; i++; if (fname == NULL) { printf("Missing log file!\n"); return(2); } //** Load it exp = exnode_exchange_load_file(fname); //** and parse the remote exnode ex = exnode_create(); if (exnode_deserialize(ex, exp, lio_gc->ess) != 0) { printf("ERROR parsing exnode! Aborting!\n"); abort(); } //** Get the default view to use seg = exnode_get_default(ex); if (seg == NULL) { printf("No default segment! Aborting!\n"); abort(); } s = (seglog_priv_t *)seg->priv; //** Verify the type if (strcmp(segment_type(seg), SEGMENT_TYPE_LOG) != 0) { printf("Invalid exnode type. Segment should be a single level log but got a type of %s\n", segment_type(seg)); abort(); } //** Now get the base type. It should NOT be a log if (strcmp(segment_type(s->base_seg), SEGMENT_TYPE_LOG) == 0) { printf("Log segments base should NOT be another log segment!\n"); abort(); } //** Truncate the log and base q = new_opque(); opque_add(q, segment_truncate(s->table_seg, lio_gc->da, 0, lio_gc->timeout)); opque_add(q, segment_truncate(s->data_seg, lio_gc->da, 0, lio_gc->timeout)); opque_add(q, segment_truncate(s->base_seg, lio_gc->da, 0, lio_gc->timeout)); err = opque_waitall(q); if (err != OP_STATE_SUCCESS) { printf("Error with truncate of initial log segment!\n"); abort(); } s->file_size = 0; s->data_size = 0; s->log_size = 0; //************************************************************************* //--------------------- Testing starts here ------------------------------- //************************************************************************* //************************************************************************* //------- Generate a base with an empty log and read back ----------------- //************************************************************************* //** Make the base buffer and write it memset(base_data, 'B', bufsize); base_data[bufsize] = '\0'; tbuffer_single(&tbuf, bufsize, base_data); ex_iovec_single(&ex_iov, 0, bufsize); { int result = gop_sync_exec(segment_write(s->base_seg, lio_gc->da, NULL, 1, &ex_iov, &tbuf, 0, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } s->file_size = bufsize; //** Since we're peeking we have to adjust the file size tbuffer_single(&tbuf, bufsize, buffer); //** Read it directly back fro mthe base to make sure that works { int result = gop_sync_exec(segment_read(s->base_seg, lio_gc->da, NULL, 1, &ex_iov, &tbuf, 0, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } buffer[bufsize] = '\0'; { int result = strcmp(buffer, base_data); assert(result == 0); } //** Do the same for the log { int result = gop_sync_exec(segment_read(seg, lio_gc->da, NULL, 1, &ex_iov, &tbuf, 0, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } { int result = compare_buffers_print(buffer, base_data, bufsize, 0); assert(result == 0); } //************************************************************************* //-- Clone the base structure and the use segment_copy to copy the data and verify -- //************************************************************************* clone = NULL; { int result = gop_sync_exec(segment_clone(seg, lio_gc->da, &clone, CLONE_STRUCTURE, NULL, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } { int result = gop_sync_exec(segment_copy(lio_gc->tpc_unlimited, lio_gc->da, NULL, seg, clone, 0, 0, bufsize, chunk_size, buffer, 0, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } memset(buffer, 0, bufsize); { int result = gop_sync_exec(segment_read(clone, lio_gc->da, NULL, 1, &ex_iov, &tbuf, 0, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } { int result = compare_buffers_print(buffer, base_data, bufsize, 0); assert(result == 0); } //************************************************************************* //-------------------- Write to the log and read back --------------------- //************************************************************************* //** We are writing 1's to the even chunks memcpy(log1_data, base_data, bufsize); memset(buffer, '1', chunk_size); for (i=0; i<n_chunks; i+=2) { memcpy(&(log1_data[i*chunk_size]), buffer, chunk_size); ex_iovec_single(&(ex_iov_table[i]), i*chunk_size, chunk_size); opque_add(q, segment_write(seg, lio_gc->da, NULL, 1, &(ex_iov_table[i]), &tbuf, 0, lio_gc->timeout)); } { int result = opque_waitall(q); assert(result == OP_STATE_SUCCESS); } //** Read it back memset(buffer, 0, bufsize); { int result = gop_sync_exec(segment_read(seg, lio_gc->da, NULL, 1, &ex_iov, &tbuf, 0, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } { int result = compare_buffers_print(buffer, log1_data, bufsize, 0); assert(result == 0); } //************************************************************************* //------------------- Merge_with base and verify -------------------------- //************************************************************************* { int result = gop_sync_exec(slog_merge_with_base(seg, lio_gc->da, chunk_size, buffer, 1, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } //** Read it back memset(buffer, 0, bufsize); { int result = gop_sync_exec(segment_read(seg, lio_gc->da, NULL, 1, &ex_iov, &tbuf, 0, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } { int result = compare_buffers_print(buffer, log1_data, bufsize, 0); assert(result == 0); } //************************************************************************* //--------------- Write to the new empty log and verify ------------------- //************************************************************************* //** We are writing 2's to *most* of the odd chunks memcpy(log1_data, buffer, bufsize); memset(buffer, '2', chunk_size); for (i=1; i<n_chunks; i+=2) { memcpy(&(log1_data[i*chunk_size]), buffer, chunk_size); ex_iovec_single(&(ex_iov_table[i]), i*chunk_size, chunk_size); opque_add(q, segment_write(seg, lio_gc->da, NULL, 1, &(ex_iov_table[i]), &tbuf, 0, lio_gc->timeout)); } { int result = opque_waitall(q); assert(result == OP_STATE_SUCCESS); } //** Read it back memset(buffer, 0, bufsize); { int result = gop_sync_exec(segment_read(seg, lio_gc->da, NULL, 1, &ex_iov, &tbuf, 0, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } { int result = compare_buffers_print(buffer, log1_data, bufsize, 0); assert(result == 0); } //************************************************************************* //---------- Replace the clones base with seg(Log1) and verify ------------ //************************************************************************* { int result = gop_sync_exec(segment_remove(clone, lio_gc->da, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } segment_destroy(clone); clone = NULL; { int result = gop_sync_exec(segment_clone(seg, lio_gc->da, &clone, CLONE_STRUCTURE, NULL, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } s = (seglog_priv_t *)clone->priv; s->base_seg = seg; s->file_size = segment_size(seg); //** Read it back memset(buffer, 0, bufsize); { int result = gop_sync_exec(segment_read(clone, lio_gc->da, NULL, 1, &ex_iov, &tbuf, 0, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } { int result = compare_buffers_print(buffer, log1_data, bufsize, 0); assert(result == 0); } //************************************************************************* //---------- Write to the clones log and verify (now have 2 logs) --------- //************************************************************************* memcpy(log2_data, log1_data, bufsize); memset(buffer, '3', 1.5*chunk_size); for (i=0; i<n_chunks; i+=4) { memcpy(&(log2_data[i*chunk_size]), buffer, 1.5*chunk_size); ex_iovec_single(&(ex_iov_table[i]), i*chunk_size, 1.5*chunk_size); opque_add(q, segment_write(clone, lio_gc->da, NULL, 1, &(ex_iov_table[i]), &tbuf, 0, lio_gc->timeout)); } { int result = opque_waitall(q); assert(result == OP_STATE_SUCCESS); } //** Read it back memset(buffer, 0, bufsize); { int result = gop_sync_exec(segment_read(clone, lio_gc->da, NULL, 1, &ex_iov, &tbuf, 0, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } { int result = compare_buffers_print(buffer, log2_data, bufsize, 0); assert(result == 0); } //************************************************************************* //---- clone2 = clone (structure and data). Verify the contents ----------- //************************************************************************* clone2 = NULL; { int result = gop_sync_exec(segment_clone(clone, lio_gc->da, &clone2, CLONE_STRUCT_AND_DATA, NULL, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } memset(buffer, 0, bufsize); { int result = gop_sync_exec(segment_read(clone2, lio_gc->da, NULL, 1, &ex_iov, &tbuf, 0, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } { int result = compare_buffers_print(buffer, log2_data, bufsize, 0); assert(result == 0); } //** We don't need this anymore so destroy it { int result = gop_sync_exec(segment_remove(clone2, lio_gc->da, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } segment_destroy(clone2); //************************************************************************* //---------------- Clone2 = clone's structure *only* ---------------------- //************************************************************************* clone2 = NULL; { int result = gop_sync_exec(segment_clone(clone, lio_gc->da, &clone2, CLONE_STRUCTURE, NULL, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } //************************************************************************* //-------------- Replace clone2's base with clone and verify -------------- //************************************************************************* s = (seglog_priv_t *)clone2->priv; { int result = gop_sync_exec(segment_remove(s->base_seg, lio_gc->da, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } segment_destroy(s->base_seg); s->base_seg = clone; s->file_size = segment_size(clone); //** Read it back memset(buffer, 0, bufsize); { int result = gop_sync_exec(segment_read(clone2, lio_gc->da, NULL, 1, &ex_iov, &tbuf, 0, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } { int result = compare_buffers_print(buffer, log2_data, bufsize, 0); assert(result == 0); } //************************************************************************* //----------- Write to Clone2 and verify (now have 3 logs) ---------------- //************************************************************************* memcpy(log3_data, log2_data, bufsize); memset(buffer, '4', chunk_size); for (i=0; i<n_chunks; i+=2) { memcpy(&(log3_data[i*chunk_size + chunk_size/3]), buffer, chunk_size); ex_iovec_single(&(ex_iov_table[i]), i*chunk_size + chunk_size/3, chunk_size); opque_add(q, segment_write(clone2, lio_gc->da, NULL, 1, &(ex_iov_table[i]), &tbuf, 0, lio_gc->timeout)); } { int result = opque_waitall(q); assert(result == OP_STATE_SUCCESS); } //** Read it back memset(buffer, 0, bufsize); { int result = gop_sync_exec(segment_read(clone2, lio_gc->da, NULL, 1, &ex_iov, &tbuf, 0, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } { int result = compare_buffers_print(buffer, log3_data, bufsize, 0); assert(result == 0); } //************************************************************************* // -- clone3 = clone2 structure and contents and verify //************************************************************************* clone3 = NULL; { int result = gop_sync_exec(segment_clone(clone2, lio_gc->da, &clone3, CLONE_STRUCT_AND_DATA, NULL, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } memset(buffer, 0, bufsize); { int result = gop_sync_exec(segment_read(clone3, lio_gc->da, NULL, 1, &ex_iov, &tbuf, 0, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } { int result = compare_buffers_print(buffer, log3_data, bufsize, 0); assert(result == 0); } //************************************************************************* //--------------------- Testing Finished ------------------------------- //************************************************************************* //** Clean up { int result = gop_sync_exec(segment_remove(clone3, lio_gc->da, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } { int result = gop_sync_exec(segment_remove(clone2, lio_gc->da, lio_gc->timeout)); assert(result == OP_STATE_SUCCESS); } segment_destroy(clone3); segment_destroy(clone2); segment_destroy(seg); exnode_exchange_destroy(exp); lio_shutdown(); return(0); }
/** * gtags_first: return first record * * @param[in] gtop #GTOP structure * @param[in] pattern tag name <br> * - may be regular expression * - may be @VAR{NULL} * @param[in] flags #GTOP_PREFIX: prefix read <br> * #GTOP_KEY: read key only <br> * #GTOP_PATH: read path only <br> * #GTOP_NOREGEX: don't use regular expression. <br> * #GTOP_IGNORECASE: ignore case distinction. <br> * #GTOP_BASICREGEX: use basic regular expression. <br> * #GTOP_NOSORT: don't sort * @return record */ GTP * gtags_first(GTOP *gtop, const char *pattern, int flags) { int regflags = 0; static regex_t reg; const char *tagline; STATIC_STRBUF(regex); strbuf_clear(regex); gtop->preg = ® gtop->key = NULL; gtop->prefix = NULL; gtop->flags = flags; gtop->dbflags = 0; gtop->readcount = 1; /* Settlement for last time if any */ if (gtop->path_hash) { strhash_close(gtop->path_hash); gtop->path_hash = NULL; } if (gtop->path_array) { free(gtop->path_array); gtop->path_array = NULL; } if (flags & GTOP_KEY) gtop->dbflags |= DBOP_KEY; if (!(flags & GTOP_BASICREGEX)) regflags |= REG_EXTENDED; /* * decide a read method */ if (pattern == NULL) gtop->preg = NULL; else if (pattern[0] == 0) return NULL; else if (!strcmp(pattern, ".*") || !strcmp(pattern, "^.*$") || !strcmp(pattern, "^") || !strcmp(pattern, "$") || !strcmp(pattern, "^.*") || !strcmp(pattern, ".*$")) { /* * Since these regular expressions match to any record, * we take sequential read method. */ gtop->preg = NULL; } else if (flags & GTOP_IGNORECASE) { regflags |= REG_ICASE; if (!isregex(pattern) || flags & GTOP_NOREGEX) { gtop->prefix = get_prefix(pattern, flags); if (gtop->openflags & GTAGS_DEBUG) if (gtop->prefix != NULL) fprintf(stderr, "Using prefix: %s\n", gtop->prefix); if (gtop->prefix == NULL) die("gtags_first: impossible (1)."); strbuf_putc(regex, '^'); strbuf_puts(regex, pattern); if (!(flags & GTOP_PREFIX)) strbuf_putc(regex, '$'); } else if (*pattern == '^' && (gtop->prefix = get_prefix(pattern, flags)) != NULL) { if (gtop->openflags & GTAGS_DEBUG) fprintf(stderr, "Using prefix: %s\n", gtop->prefix); strbuf_puts(regex, pattern); } else { strbuf_puts(regex, pattern); } } else { if (!isregex(pattern) || flags & GTOP_NOREGEX) { if (flags & GTOP_PREFIX) gtop->dbflags |= DBOP_PREFIX; gtop->key = pattern; gtop->preg = NULL; } else if (*pattern == '^' && (gtop->key = get_prefix(pattern, flags)) != NULL) { if (gtop->openflags & GTAGS_DEBUG) fprintf(stderr, "Using prefix: %s\n", gtop->key); gtop->dbflags |= DBOP_PREFIX; gtop->preg = NULL; } else { strbuf_puts(regex, pattern); } } if (gtop->prefix) { if (gtop->key) die("gtags_first: impossible (2)."); gtop->key = gtop->prefix; gtop->dbflags |= DBOP_PREFIX; } if (strbuf_getlen(regex) > 0) { if (gtop->preg == NULL) die("gtags_first: impossible (3)."); if (regcomp(gtop->preg, strbuf_value(regex), regflags) != 0) die("invalid regular expression."); } /* * If GTOP_PATH is set, at first, we collect all path names in a pool and * sort them. gtags_first() and gtags_next() returns one of the pool. */ if (gtop->flags & GTOP_PATH) { struct sh_entry *entry; char *p; const char *cp; unsigned long i; gtop->path_hash = strhash_open(HASHBUCKETS); /* * Pool path names. * * fid path name * +-------------------------- * |100 ./aaa/a.c * |105 ./aaa/b.c * ... */ again0: for (tagline = dbop_first(gtop->dbop, gtop->key, gtop->preg, gtop->dbflags); tagline != NULL; tagline = dbop_next(gtop->dbop)) { VIRTUAL_GRTAGS_GSYMS_PROCESSING(gtop); /* extract file id */ p = locatestring(tagline, " ", MATCH_FIRST); if (p == NULL) die("Invalid tag record. '%s'\n", tagline); *p = '\0'; entry = strhash_assign(gtop->path_hash, tagline, 1); /* new entry: get path name and set. */ if (entry->value == NULL) { cp = gpath_fid2path(tagline, NULL); if (cp == NULL) die("GPATH is corrupted.(file id '%s' not found)", tagline); entry->value = strhash_strdup(gtop->path_hash, cp, 0); } } if (gtop->prefix && gtags_restart(gtop)) goto again0; /* * Sort path names. * * fid path name path_array (sort) * +-------------------------- +---+ * |100 ./aaa/a.c <-------* | * |105 ./aaa/b.c <-------* | * ... ... */ gtop->path_array = (char **)check_malloc(gtop->path_hash->entries * sizeof(char *)); i = 0; for (entry = strhash_first(gtop->path_hash); entry != NULL; entry = strhash_next(gtop->path_hash)) gtop->path_array[i++] = entry->value; if (i != gtop->path_hash->entries) die("Something is wrong. 'i = %lu, entries = %lu'" , i, gtop->path_hash->entries); if (!(gtop->flags & GTOP_NOSORT)) qsort(gtop->path_array, gtop->path_hash->entries, sizeof(char *), compare_path); gtop->path_count = gtop->path_hash->entries; gtop->path_index = 0; if (gtop->path_index >= gtop->path_count) return NULL; gtop->gtp.path = gtop->path_array[gtop->path_index++]; return >op->gtp; } else if (gtop->flags & GTOP_KEY) { again1: for (gtop->gtp.tag = dbop_first(gtop->dbop, gtop->key, gtop->preg, gtop->dbflags); gtop->gtp.tag != NULL; gtop->gtp.tag = dbop_next(gtop->dbop)) { VIRTUAL_GRTAGS_GSYMS_PROCESSING(gtop); break; } if (gtop->gtp.tag == NULL) { if (gtop->prefix && gtags_restart(gtop)) goto again1; } return gtop->gtp.tag ? >op->gtp : NULL; } else { if (gtop->vb == NULL) gtop->vb = varray_open(sizeof(GTP), 200); else varray_reset(gtop->vb); if (gtop->segment_pool == NULL) gtop->segment_pool = pool_open(); else pool_reset(gtop->segment_pool); if (gtop->path_hash == NULL) gtop->path_hash = strhash_open(HASHBUCKETS); else strhash_reset(gtop->path_hash); again2: tagline = dbop_first(gtop->dbop, gtop->key, gtop->preg, gtop->dbflags); if (tagline == NULL) { if (gtop->prefix && gtags_restart(gtop)) goto again2; return NULL; } /* * Dbop_next() wil read the same record again. */ dbop_unread(gtop->dbop); /* * Read a tag segment with sorting. */ segment_read(gtop); return >op->gtp_array[gtop->gtp_index++]; } }
op_status_t segment_copy_func(void *arg, int id) { segment_copy_t *sc = (segment_copy_t *)arg; tbuffer_t *wbuf, *rbuf, *tmpbuf; tbuffer_t tbuf1, tbuf2; int err; ex_off_t bufsize; ex_off_t rpos, wpos, rlen, wlen, tlen, nbytes, dend; ex_iovec_t rex, wex; opque_t *q; op_generic_t *rgop, *wgop; op_status_t status; //** Set up the buffers bufsize = sc->bufsize / 2; //** The buffer is split for R/W tbuffer_single(&tbuf1, bufsize, sc->buffer); tbuffer_single(&tbuf2, bufsize, &(sc->buffer[bufsize])); rbuf = &tbuf1; wbuf = &tbuf2; //** Check the length nbytes = segment_size(sc->src) - sc->src_offset; if (nbytes < 0) { rlen = bufsize; } else { rlen = (nbytes > bufsize) ? bufsize : nbytes; } if ((sc->len != -1) && (sc->len < nbytes)) nbytes = sc->len; //** Go ahead and reserve the space in the destintaion dend = sc->dest_offset + nbytes; log_printf(1, "reserving space=" XOT "\n", dend); gop_sync_exec(segment_truncate(sc->dest, sc->da, -dend, sc->timeout)); //** Read the initial block rpos = sc->src_offset; wpos = sc->dest_offset; // rlen = (nbytes > bufsize) ? bufsize : nbytes; wlen = 0; ex_iovec_single(&rex, rpos, rlen); rpos += rlen; nbytes -= rlen; rgop = segment_read(sc->src, sc->da, sc->rw_hints, 1, &rex, rbuf, 0, sc->timeout); err = gop_waitall(rgop); if (err != OP_STATE_SUCCESS) { log_printf(1, "Intial read failed! src=%" PRIu64 " rpos=" XOT " len=" XOT "\n", segment_id(sc->src), rpos, rlen); gop_free(rgop, OP_DESTROY); return(op_failure_status); } gop_free(rgop, OP_DESTROY); q = new_opque(); do { //** Swap the buffers tmpbuf = rbuf; rbuf = wbuf; wbuf = tmpbuf; tlen = rlen; rlen = wlen; wlen = tlen; log_printf(1, "sseg=" XIDT " dseg=" XIDT " wpos=%" PRId64 " rlen=%" PRId64 " wlen=%" PRId64 "\n", segment_id(sc->src), segment_id(sc->dest), wpos, rlen, wlen); //** Start the write ex_iovec_single(&wex, wpos, wlen); wpos += wlen; wgop = segment_write(sc->dest, sc->da, sc->rw_hints, 1, &wex, wbuf, 0, sc->timeout); opque_add(q, wgop); //** Read in the next block // rlen = (nbytes > bufsize) ? bufsize : nbytes; if (nbytes < 0) { rlen = bufsize; } else { rlen = (nbytes > bufsize) ? bufsize : nbytes; } if (rlen > 0) { ex_iovec_single(&rex, rpos, rlen); rpos += rlen; nbytes -= rlen; rgop = segment_read(sc->src, sc->da, sc->rw_hints, 1, &rex, rbuf, 0, sc->timeout); opque_add(q, rgop); } err = opque_waitall(q); if (err != OP_STATE_SUCCESS) { log_printf(1, "ERROR read/write failed! src=" XIDT " rpos=" XOT " len=" XOT "\n", segment_id(sc->src), rpos, rlen); opque_free(q, OP_DESTROY); return(op_failure_status); } } while (rlen > 0); opque_free(q, OP_DESTROY); if (sc->truncate == 1) { //** Truncate if wanted gop_sync_exec(segment_truncate(sc->dest, sc->da, wpos, sc->timeout)); } status = op_success_status; status.error_code = rpos; return(status); }
op_status_t segment_get_func(void *arg, int id) { segment_copy_t *sc = (segment_copy_t *)arg; tbuffer_t *wbuf, *rbuf, *tmpbuf; tbuffer_t tbuf1, tbuf2; char *rb, *wb, *tb; ex_off_t bufsize; int err; ex_off_t rpos, wpos, rlen, wlen, tlen, nbytes, got, total; ex_iovec_t rex; apr_time_t loop_start, file_start; double dt_loop, dt_file; op_generic_t *gop; op_status_t status; //** Set up the buffers bufsize = sc->bufsize / 2; //** The buffer is split for R/W rb = sc->buffer; wb = &(sc->buffer[bufsize]); tbuffer_single(&tbuf1, bufsize, rb); tbuffer_single(&tbuf2, bufsize, wb); rbuf = &tbuf1; wbuf = &tbuf2; status = op_success_status; //** Read the initial block rpos = sc->src_offset; wpos = 0; nbytes = segment_size(sc->src) - sc->src_offset; if (nbytes < 0) { rlen = bufsize; } else { rlen = (nbytes > bufsize) ? bufsize : nbytes; } log_printf(5, "FILE fd=%p\n", sc->fd); ex_iovec_single(&rex, rpos, rlen); wlen = 0; rpos += rlen; nbytes -= rlen; loop_start = apr_time_now(); gop = segment_read(sc->src, sc->da, sc->rw_hints, 1, &rex, rbuf, 0, sc->timeout); err = gop_waitall(gop); if (err != OP_STATE_SUCCESS) { log_printf(1, "Intial read failed! src=" XIDT " rpos=" XOT " len=" XOT "\n", segment_id(sc->src), rpos, rlen); gop_free(gop, OP_DESTROY); return(op_failure_status); } gop_free(gop, OP_DESTROY); total = 0; do { //** Swap the buffers tb = rb; rb = wb; wb = tb; tmpbuf = rbuf; rbuf = wbuf; wbuf = tmpbuf; tlen = rlen; rlen = wlen; wlen = tlen; log_printf(1, "sseg=" XIDT " rpos=" XOT " wpos=" XOT " rlen=" XOT " wlen=" XOT " nbytes=" XOT "\n", segment_id(sc->src), rpos, wpos, rlen, wlen, nbytes); //** Read in the next block if (nbytes < 0) { rlen = bufsize; } else { rlen = (nbytes > bufsize) ? bufsize : nbytes; } if (rlen > 0) { ex_iovec_single(&rex, rpos, rlen); loop_start = apr_time_now(); gop = segment_read(sc->src, sc->da, sc->rw_hints, 1, &rex, rbuf, 0, sc->timeout); gop_start_execution(gop); //** Start doing the transfer rpos += rlen; nbytes -= rlen; } //** Start the write file_start = apr_time_now(); got = fwrite(wb, 1, wlen, sc->fd); dt_file = apr_time_now() - file_start; dt_file /= (double)APR_USEC_PER_SEC; total += got; log_printf(5, "sid=" XIDT " fwrite(wb,1," XOT ", sc->fd)=" XOT " total=" XOT "\n", segment_id(sc->src), wlen, got, total); if (wlen != got) { log_printf(1, "ERROR from fread=%d dest sid=" XIDT "\n", errno, segment_id(sc->dest)); status = op_failure_status; gop_waitall(gop); gop_free(gop, OP_DESTROY); goto fail; } wpos += wlen; //** Wait for the read to complete if (rlen > 0) { err = gop_waitall(gop); gop_free(gop, OP_DESTROY); if (err != OP_STATE_SUCCESS) { log_printf(1, "ERROR write(dseg=" XIDT ") failed! wpos=" XOT " len=" XOT "\n", segment_id(sc->dest), wpos, wlen); status = op_failure_status; goto fail; } } dt_loop = apr_time_now() - loop_start; dt_loop /= (double)APR_USEC_PER_SEC; log_printf(1, "dt_loop=%lf dt_file=%lf\n", dt_loop, dt_file); } while (rlen > 0); fail: return(status); }