void Hash_clean(Hash *self) { assume_ptr(self); Hash_clear(self); free(self->buckets); self->buckets = NULL; self->bucketCount = 0; }
/** * ハッシュテーブルを解放する * * @param hash 解放するハッシュテーブル。解放後は使用不能になる。 */ Result Hash_free(Hash *hash) { size_t i; if(!hash) { return R_NG; } /* 全エントリの破棄 */ if(Hash_clear(hash) != R_OK) { return R_OK; } /* ルート配列の破棄 */ free(hash->entries); hash->entries = NULL; hash->factor = 0; hash->length = 0; return R_OK; }
/** * 指定サイズの部分文字列で、2つ以上存在するものの位置をビット配列にセットする * * @param source 文字列全体 * @param dest 出力先ビット列 * @param oldBits 前回検索時のビット列 * @param len 部分文字列の長さ * @param hash ハッシュテーブル * * @return 一致する部分文字列があればR_OK。なければR_NOTFOUND */ Result scanSameSubstrings(const Array *source, Array *dest, const Array *oldBits, size_t len, Hash *hash) { size_t slen = source->length - len + 1; size_t i = 0; size_t j = 0; int found = 0; Result result = R_NG; Hash_clear(hash); /* 指定サイズの全部分文字列について、ハッシュを使用して重複しているものを洗い出す */ for(i = 0; i < (slen - 1); ++i) { const char *p; const HashEntry *before = NULL; /* 前回検査時の重複文字列の位置でなければスキップ */ if(!Array_get(oldBits, i)) { continue; } /* 現在位置の部分文字列が重複しているか検査する。未登録であればハッシュに登録する */ p = Array_pointer(source, i); if(Hash_putIfAbsent(hash, p, len, &before) != R_OK) { return R_NG; } /* 重複している部分文字列だった場合、以前と今回の出現箇所のビットを立てる */ if(before) { Array_set(dest, before->p - (const char *)source->p, 1); Array_set(dest, i, 1); found = 1; } } return found ? R_OK : R_NOTFOUND; }