mercurial/manifest.c
changeset 24228 542c891274b2
parent 24214 a5f1bccd2996
child 24286 40528ad1b1e8
equal deleted inserted replaced
24227:8ec2df32bd39 24228:542c891274b2
   361 	hit->deleted = true;
   361 	hit->deleted = true;
   362 	self->livelines--;
   362 	self->livelines--;
   363 	return 0;
   363 	return 0;
   364 }
   364 }
   365 
   365 
       
   366 /* Do a binary search for the insertion point for new, creating the
       
   367  * new entry if needed. */
       
   368 static int internalsetitem(lazymanifest *self, line *new) {
       
   369 	int start = 0, end = self->numlines;
       
   370 	while (start < end) {
       
   371 		int pos = start + (end - start) / 2;
       
   372 		int c = linecmp(new, self->lines + pos);
       
   373 		if (c < 0)
       
   374 			end = pos;
       
   375 		else if (c > 0)
       
   376 			start = pos + 1;
       
   377 		else {
       
   378 			if (self->lines[pos].deleted)
       
   379 				self->livelines++;
       
   380 			start = pos;
       
   381 			goto finish;
       
   382 		}
       
   383 	}
       
   384 	/* being here means we need to do an insert */
       
   385 	if (!realloc_if_full(self)) {
       
   386 		PyErr_NoMemory();
       
   387 		return -1;
       
   388 	}
       
   389 	memmove(self->lines + start + 1, self->lines + start,
       
   390 		(self->numlines - start) * sizeof(line));
       
   391 	self->numlines++;
       
   392 	self->livelines++;
       
   393 finish:
       
   394 	self->lines[start] = *new;
       
   395 	self->dirty = true;
       
   396 	return 0;
       
   397 }
       
   398 
   366 static int lazymanifest_setitem(
   399 static int lazymanifest_setitem(
   367 	lazymanifest *self, PyObject *key, PyObject *value)
   400 	lazymanifest *self, PyObject *key, PyObject *value)
   368 {
   401 {
   369 	char *path;
   402 	char *path;
   370 	Py_ssize_t plen;
   403 	Py_ssize_t plen;
   376 	Py_ssize_t flen;
   409 	Py_ssize_t flen;
   377 	size_t dlen;
   410 	size_t dlen;
   378 	char *dest;
   411 	char *dest;
   379 	int i;
   412 	int i;
   380 	line new;
   413 	line new;
   381 	line *hit;
       
   382 	if (!PyString_Check(key)) {
   414 	if (!PyString_Check(key)) {
   383 		PyErr_Format(PyExc_TypeError,
   415 		PyErr_Format(PyExc_TypeError,
   384 			     "setitem: manifest keys must be a string.");
   416 			     "setitem: manifest keys must be a string.");
   385 		return -1;
   417 		return -1;
   386 	}
   418 	}
   444 	if (hlen > 20) {
   476 	if (hlen > 20) {
   445 		new.hash_suffix = hash[20];
   477 		new.hash_suffix = hash[20];
   446 	}
   478 	}
   447 	new.from_malloc = true;     /* is `start` a pointer we allocated? */
   479 	new.from_malloc = true;     /* is `start` a pointer we allocated? */
   448 	new.deleted = false;        /* is this entry deleted? */
   480 	new.deleted = false;        /* is this entry deleted? */
   449 	hit = bsearch(&new, self->lines, self->numlines,
   481 	if (internalsetitem(self, &new)) {
   450 		      sizeof(line), &linecmp);
   482 		return -1;
   451 	self->dirty = true;
       
   452 	if (hit) {
       
   453 		/* updating a line we already had */
       
   454 		if (hit->from_malloc) {
       
   455 			free(hit->start);
       
   456 		}
       
   457 		if (hit->deleted) {
       
   458 			self->livelines++;
       
   459 		}
       
   460 		*hit = new;
       
   461 	} else {
       
   462 		/* new line */
       
   463 		if (!realloc_if_full(self)) {
       
   464 			PyErr_NoMemory();
       
   465 			return -1;
       
   466 		}
       
   467 		self->lines[self->numlines++] = new;
       
   468 		self->livelines++;
       
   469 		/* TODO: do a binary search and insert rather than
       
   470 		 * append and qsort. Also offer a batch-insert
       
   471 		 * interface, which should be a nice little
       
   472 		 * performance win.
       
   473 		 */
       
   474 		qsort(self->lines, self->numlines, sizeof(line), &linecmp);
       
   475 	}
   483 	}
   476 	return 0;
   484 	return 0;
   477 }
   485 }
   478 
   486 
   479 static PyMappingMethods lazymanifest_mapping_methods = {
   487 static PyMappingMethods lazymanifest_mapping_methods = {