1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18#include "arrow/ipc/dictionary.h"
19
20#include <cstdint>
21#include <memory>
22#include <sstream>
23#include <utility>
24
25#include "arrow/status.h"
26
27namespace arrow {
28namespace ipc {
29
30DictionaryMemo::DictionaryMemo() {}
31
32// Returns KeyError if dictionary not found
33Status DictionaryMemo::GetDictionary(int64_t id,
34 std::shared_ptr<Array>* dictionary) const {
35 auto it = id_to_dictionary_.find(id);
36 if (it == id_to_dictionary_.end()) {
37 return Status::KeyError("Dictionary with id ", id, " not found");
38 }
39 *dictionary = it->second;
40 return Status::OK();
41}
42
43int64_t DictionaryMemo::GetId(const std::shared_ptr<Array>& dictionary) {
44 intptr_t address = reinterpret_cast<intptr_t>(dictionary.get());
45 auto it = dictionary_to_id_.find(address);
46 if (it != dictionary_to_id_.end()) {
47 // Dictionary already observed, return the id
48 return it->second;
49 } else {
50 int64_t new_id = static_cast<int64_t>(dictionary_to_id_.size());
51 dictionary_to_id_[address] = new_id;
52 id_to_dictionary_[new_id] = dictionary;
53 return new_id;
54 }
55}
56
57bool DictionaryMemo::HasDictionary(const std::shared_ptr<Array>& dictionary) const {
58 intptr_t address = reinterpret_cast<intptr_t>(dictionary.get());
59 auto it = dictionary_to_id_.find(address);
60 return it != dictionary_to_id_.end();
61}
62
63bool DictionaryMemo::HasDictionaryId(int64_t id) const {
64 auto it = id_to_dictionary_.find(id);
65 return it != id_to_dictionary_.end();
66}
67
68Status DictionaryMemo::AddDictionary(int64_t id,
69 const std::shared_ptr<Array>& dictionary) {
70 if (HasDictionaryId(id)) {
71 return Status::KeyError("Dictionary with id ", id, " already exists");
72 }
73 intptr_t address = reinterpret_cast<intptr_t>(dictionary.get());
74 id_to_dictionary_[id] = dictionary;
75 dictionary_to_id_[address] = id;
76 return Status::OK();
77}
78
79} // namespace ipc
80} // namespace arrow
81