this repo has no description
at trunk 91 lines 3.1 kB view raw
1/* Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) */ 2#pragma once 3 4#include "globals.h" 5#include "handles-decl.h" 6#include "objects.h" 7#include "runtime.h" 8#include "thread.h" 9 10namespace py { 11 12// Add `LargeStr` object `str` to the intern set `data`. Sets `*result` to 13// an equal existing string in the table and returns `false` or inserts `str` 14// to the table and returns `true`. The return value should be used to count 15// down a "remaining" counter and grow the set when necessary. 16bool internSetAdd(Thread* thread, RawMutableTuple data, const Object& str, 17 RawObject* result); 18 19// Sets `*result` to an existing string object equal to `bytes` and returns 20// `false` or creates a new `LargeStr` from `bytes`, inserts it into the table 21// and returns `true`. The return value should be used to count down a 22// "remaining" counter and grow the set when necessary. 23bool internSetAddFromAll(Thread* thread, RawMutableTuple data, View<byte> bytes, 24 RawObject* result); 25 26word internSetComputeRemaining(word data_length); 27 28bool internSetContains(RawMutableTuple data, RawLargeStr str); 29 30RawObject internSetGrow(Thread* thread, RawMutableTuple data, 31 word* remaining_out); 32 33inline bool internSetAddFromAll(Thread* thread, RawMutableTuple data, 34 View<byte> bytes, RawObject* result) { 35 DCHECK(bytes.length() > SmallStr::kMaxLength, "only need to intern LargeStr"); 36 Runtime* runtime = thread->runtime(); 37 word hash = runtime->bytesHash(bytes); 38 DCHECK(Utils::isPowerOfTwo(data.length()), "table size must be power of two"); 39 word mask = data.length() - 1; 40 word index = hash & mask; 41 word num_probes = 0; 42 for (;;) { 43 RawObject slot = data.at(index); 44 if (slot == SmallInt::fromWord(0)) { 45 RawLargeStr new_str = LargeStr::cast(runtime->newStrWithAll(bytes)); 46 new_str.setHeader(new_str.header().withHashCode(hash)); 47 data.atPut(index, new_str); 48 *result = new_str; 49 return true; 50 } 51 if (LargeStr::cast(slot).equalsBytes(bytes)) { 52 *result = slot; 53 return false; 54 } 55 56 num_probes++; 57 index = (index + num_probes) & mask; 58 } 59} 60 61inline bool internSetAdd(Thread* thread, RawMutableTuple data, 62 const Object& str, RawObject* result) { 63 DCHECK(str.isLargeStr(), "expected large string"); 64 Runtime* runtime = thread->runtime(); 65 word hash = runtime->valueHash(*str); 66 DCHECK(Utils::isPowerOfTwo(data.length()), "table size must be power of two"); 67 word mask = data.length() - 1; 68 word index = hash & mask; 69 word num_probes = 0; 70 for (;;) { 71 RawObject slot = data.at(index); 72 if (slot == str) { 73 *result = *str; 74 return false; 75 } 76 if (slot == SmallInt::fromWord(0)) { 77 data.atPut(index, *str); 78 *result = *str; 79 return true; 80 } 81 if (LargeStr::cast(slot).equals(LargeStr::cast(*str))) { 82 *result = slot; 83 return false; 84 } 85 86 num_probes++; 87 index = (index + num_probes) & mask; 88 } 89} 90 91} // namespace py