Beispiel #1
0
struct conn_target *calculate_key_target (const char *key, int key_len) {
  int i = 0;
  unsigned hash;
  struct conn_target *S;
  static char key_buffer[MAX_KEY_LEN+4];

  if (!CC->tot_buckets || key_len <= 0 || key_len > MAX_KEY_LEN) {
    return 0;
  }

  if (key_len >= 3 && key[key_len - 1] == '$' && key[key_len - 2] == '#' && key[key_len - 3] == '@') {
    char *tmp;
    for (tmp = (char *)(key + key_len - 4); tmp >= (char *)key; --tmp) {
      if (*tmp == '#') {
        break;
      }
    }
    if (tmp >= (char *)key) {
      char *ttt;
      unsigned r = strtoul (tmp + 1, &ttt, 10);
      if (ttt > tmp + 1 && ttt == key + key_len - 3) {
        S = CC->buckets[r % CC->tot_buckets];
        return S;
      }
    }
  }

  if ((CC->cluster_mode & 255) == CLUSTER_MODE_RANDOM) {
    for (i = 0; i < 10; i++) {
      S = CC->buckets[lrand48 () % CC->tot_buckets];
      if (S && S->active_outbound_connections) {
        return S;
      }
    }
    return 0;
  }

  if ((CC->cluster_mode & 255) == CLUSTER_MODE_FIRSTINT) {
    unsigned long long longhash = extract_num (key, key_len, 0);
    if (verbosity > 1) {
      fprintf (stderr, "extract_num(%.*s) = %llu\n", key_len, key, longhash);
    }
    if ((long long) longhash == -1) {
      return 0;
    }
    if (CC->step > 0) {
      longhash /= CC->step;
    }
    S = CC->buckets[longhash % CC->tot_buckets];
    return S->active_outbound_connections ? S : 0;
  }

  if ((CC->cluster_mode & 255) > CLUSTER_MODE_FIRSTINT && (CC->cluster_mode & 255) <= CLUSTER_MODE_FIFTHINT) {
    int k = (CC->cluster_mode & 255) - (CLUSTER_MODE_FIRSTINT - 1);
    char *p1 = (char *) key, *p2;
    int clen = key_len;
    unsigned long long longhash = 0;
    for (i = 0; i < k; i++) {
      longhash = extract_num (p1, clen, &p2);
      if ((long long) longhash == -1) {
        return 0;
      }
      assert (p2 >= p1 && p2 <= p1 + clen);
      clen -= p2 - p1;
      p1 = p2;
    }
    if (CC->step > 0) {
      longhash /= CC->step;
    }
    S = CC->buckets[longhash % CC->tot_buckets];
    return S->active_outbound_connections ? S : 0;
  }


  if (DOT_EXTENSION) {
    char *dot_pos = memchr (key, '.', key_len);
    if (dot_pos) {
      key_len = dot_pos - key;
    }
  }

  if (CC->points) {
    unsigned long long x = crc64 (key, key_len);
    int a = -1, b = CC->tot_buckets * CC->points_num, c;
    while (b - a > 1) {
      c = (a + b) >> 1;
      if (x < CC->points[c].x) {
        b = c;
      } else {
        a = c;
      }
    }

    assert (CC->points_num > 0);

    for (i = 0; i < MAX_RETRIES; i++) {
      if (a < 0) {
        a += CC->points_num;
      }
      S = CC->points[a].target;
      if (S->active_outbound_connections) {
        return S;
      }
      a--;
    }

    return 0;
  }
Beispiel #2
0
static int cache_record_deserialize (struct cache_record *rec,
           const char *serialized, size_t size, int skip_tags)
{
	const char *p = serialized;
	size_t bytes_left = size;
	size_t str_len;

	assert (rec != NULL);
	assert (serialized != NULL);

	if (!skip_tags)
		rec->tags = tags_new ();
	else
		rec->tags = NULL;

#define extract_num(var) \
	do { \
		if (bytes_left < sizeof(var)) \
			goto err; \
		memcpy (&var, p, sizeof(var)); \
		bytes_left -= sizeof(var); \
		p += sizeof(var); \
	} while (0)

#define extract_str(var) \
	do { \
		if (bytes_left < sizeof(str_len)) \
			goto err; \
		memcpy (&str_len, p, sizeof(str_len)); \
		p += sizeof(str_len); \
		if (bytes_left < str_len) \
			goto err; \
		var = xmalloc (str_len + 1); \
		memcpy (var, p, str_len); \
		var[str_len] = '\0'; \
		p += str_len; \
	} while (0)

	extract_num (rec->mod_time);
	extract_num (rec->atime);

	if (!skip_tags) {
		extract_str (rec->tags->artist);
		extract_str (rec->tags->album);
		extract_str (rec->tags->title);
		extract_num (rec->tags->track);
		extract_num (rec->tags->time);

		if (rec->tags->title)
			rec->tags->filled |= TAGS_COMMENTS;
		else {
			if (rec->tags->artist)
				free (rec->tags->artist);
			rec->tags->artist = NULL;

			if (rec->tags->album)
				free (rec->tags->album);
			rec->tags->album = NULL;
		}

		if (rec->tags->time >= 0)
			rec->tags->filled |= TAGS_TIME;
	}

	return 1;

err:
	logit ("Cache record deserialization error at %tdB", p - serialized);
	tags_free (rec->tags);
	rec->tags = NULL;
	return 0;
}
int firstint_fits (const char *const key, int key_len) {
  unsigned long long id = extract_num (key, key_len, NULL);
  return id % copy_mod == copy_rem;
}
static uri_template_expr *build_expr(char *tpl, int len)
{
	uri_template_expr *expr;
	uri_template_var  *var = uri_template_var_create();
	char *name = tpl, *start = tpl, *prefix;
	
	if (IS_OPERATOR(*tpl)) {
		expr = uri_template_expr_create(*tpl++);
		name = tpl;
	} else {
		expr = uri_template_expr_create(0);
	}
	
	while (tpl - start <= len) {
		switch(*tpl) {
			case '%':
				if (name + len - tpl > 2) {
					if (isxdigit(*(tpl + 1))) {
						if (isxdigit(*(++tpl + 1))) {
							tpl++;
						} else {
							expr->error = URI_TEMPLATE_ERROR;
						}
					} else {
						expr->error = URI_TEMPLATE_ERROR;
					}
				} else {
					expr->error = URI_TEMPLATE_ERROR;
				}
				
				break;
			case ':':
				prefix = ++tpl;

				if (*tpl >= '1' && *tpl++ <= '9') {
					while (isdigit(*tpl)) {
						tpl++;
					}
					
					if (*tpl == ',' || *tpl == '}') {
						if (tpl - prefix < 5) {
							var->length = extract_num(tpl - (tpl - prefix), tpl - prefix);
						} else {
							expr->error = URI_TEMPLATE_ERROR;
						}
					  
						tpl--;
					} else {
						expr->error = URI_TEMPLATE_ERROR;
					}
				} else {
					expr->error = URI_TEMPLATE_ERROR;
				}
				
				break;
			case '*':
				if (*(tpl + 1) == '}' || *(tpl + 1) == ',') {
					var->explode = 1;
				} else {
					expr->error = URI_TEMPLATE_ERROR;
				}
				
				break;
			case ',':
			case '}':
				var->name = estrndup(name, tpl - name - SHIFT_BACK(var));
				uri_template_expr_add_var(expr, var);
				
				if (*tpl == ',') {
					var = uri_template_var_create();
					name = tpl + 1;
				}
				
				break;
			default:
				expr->error |= !(isalnum(*tpl) || *tpl == '_' || *tpl == '.');
				
				break;
		}
		
		tpl++;
	}

	return expr;
}